1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Heikki Hannikainen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #include "debug_menu.h"
35 #include "powermgmt.h"
39 #include "mp3_playback.h"
42 #include "statusbar.h"
53 #include "lcd-remote.h"
56 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
64 #include "eeprom_24cxx.h"
65 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
68 #if (CONFIG_STORAGE & STORAGE_ATA)
77 #ifdef HAVE_LCD_BITMAP
78 #include "scrollbar.h"
79 #include "peakmeter.h"
82 #if CONFIG_CODEC == SWCODEC
84 #include "buffering.h"
86 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
90 #ifdef IRIVER_H300_SERIES
91 #include "pcf50606.h" /* for pcf50606_read */
98 #if CONFIG_RTC == RTC_PCF50605
101 #include "appevents.h"
102 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
103 #include "debug-target.h"
106 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
107 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
108 || CONFIG_CPU == AS3525v2
114 #include "pmu-target.h"
118 #include "usb_core.h"
121 #if defined(IPOD_ACCESSORY_PROTOCOL)
125 /*---------------------------------------------------*/
126 /* SPECIAL DEBUG STUFF */
127 /*---------------------------------------------------*/
128 extern struct thread_entry threads
[MAXTHREADS
];
130 static char thread_status_char(unsigned status
)
132 static const char thread_status_chars
[THREAD_NUM_STATES
+1] =
134 [0 ... THREAD_NUM_STATES
] = '?',
135 [STATE_RUNNING
] = 'R',
136 [STATE_BLOCKED
] = 'B',
137 [STATE_SLEEPING
] = 'S',
138 [STATE_BLOCKED_W_TMO
] = 'T',
139 [STATE_FROZEN
] = 'F',
140 [STATE_KILLED
] = 'K',
143 if (status
> THREAD_NUM_STATES
)
144 status
= THREAD_NUM_STATES
;
146 return thread_status_chars
[status
];
149 static const char* threads_getname(int selected_item
, void *data
,
150 char *buffer
, size_t buffer_len
)
153 struct thread_entry
*thread
;
157 if (selected_item
< (int)NUM_CORES
)
159 snprintf(buffer
, buffer_len
, "Idle (%d): %2d%%", selected_item
,
160 idle_stack_usage(selected_item
));
164 selected_item
-= NUM_CORES
;
167 thread
= &threads
[selected_item
];
169 if (thread
->state
== STATE_KILLED
)
171 snprintf(buffer
, buffer_len
, "%2d: ---", selected_item
);
175 thread_get_name(name
, 32, thread
);
177 snprintf(buffer
, buffer_len
,
178 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
180 IF_COP(thread
->core
,)
181 #ifdef HAVE_SCHEDULER_BOOSTCTRL
182 (thread
->cpu_boost
) ? '+' :
184 ((thread
->state
== STATE_RUNNING
) ? '*' : ' '),
185 thread_status_char(thread
->state
),
186 IF_PRIO(thread
->base_priority
, thread
->priority
, )
187 thread_stack_usage(thread
), name
);
192 static int dbg_threads_action_callback(int action
, struct gui_synclist
*lists
)
195 #ifdef ROCKBOX_HAS_LOGF
196 if (action
== ACTION_STD_OK
)
198 int selpos
= gui_synclist_get_sel_pos(lists
);
200 if (selpos
>= NUM_CORES
)
201 remove_thread(threads
[selpos
- NUM_CORES
].id
);
203 remove_thread(threads
[selpos
].id
);
205 return ACTION_REDRAW
;
207 #endif /* ROCKBOX_HAS_LOGF */
208 if (action
== ACTION_NONE
)
209 action
= ACTION_REDRAW
;
213 static bool dbg_os(void)
215 struct simplelist_info info
;
216 simplelist_info_init(&info
, IF_COP("Core and ") "Stack usage:",
220 MAXTHREADS
+NUM_CORES
,
223 #ifndef ROCKBOX_HAS_LOGF
224 info
.hide_selection
= true;
225 info
.scroll_all
= true;
227 info
.action_callback
= dbg_threads_action_callback
;
228 info
.get_name
= threads_getname
;
229 return simplelist_show_list(&info
);
232 #ifdef HAVE_LCD_BITMAP
233 #if CONFIG_CODEC != SWCODEC
235 static bool dbg_audio_thread(void)
237 struct audio_debug d
;
239 lcd_setfont(FONT_SYSFIXED
);
243 if (action_userabort(HZ
/5))
246 audio_get_debugdata(&d
);
250 lcd_putsf(0, 0, "read: %x", d
.audiobuf_read
);
251 lcd_putsf(0, 1, "write: %x", d
.audiobuf_write
);
252 lcd_putsf(0, 2, "swap: %x", d
.audiobuf_swapwrite
);
253 lcd_putsf(0, 3, "playing: %d", d
.playing
);
254 lcd_putsf(0, 4, "playable: %x", d
.playable_space
);
255 lcd_putsf(0, 5, "unswapped: %x", d
.unswapped_space
);
257 /* Playable space left */
258 gui_scrollbar_draw(&screens
[SCREEN_MAIN
],0, 6*8, 112, 4, d
.audiobuflen
, 0,
259 d
.playable_space
, HORIZONTAL
);
261 /* Show the watermark limit */
262 gui_scrollbar_draw(&screens
[SCREEN_MAIN
],0, 6*8+4, 112, 4, d
.audiobuflen
, 0,
263 d
.low_watermark_level
, HORIZONTAL
);
265 lcd_putsf(0, 7, "wm: %x - %x",
266 d
.low_watermark_level
, d
.lowest_watermark_level
);
270 lcd_setfont(FONT_UI
);
273 #endif /* !SIMULATOR */
274 #else /* CONFIG_CODEC == SWCODEC */
275 static unsigned int ticks
, freq_sum
;
276 #ifndef CPU_MULTI_FREQUENCY
277 static unsigned int boost_ticks
;
280 static void dbg_audio_task(void)
282 #ifdef CPUFREQ_NORMAL
283 #ifndef CPU_MULTI_FREQUENCY
284 if(FREQ
> CPUFREQ_NORMAL
)
287 freq_sum
+= FREQ
/1000000; /* in MHz */
292 static bool dbg_buffering_thread(void)
298 size_t bufsize
= pcmbuf_get_bufsize();
299 int pcmbufdescs
= pcmbuf_descs();
300 struct buffering_debug d
;
301 size_t filebuflen
= audio_get_filebuflen();
302 /* This is a size_t, but call it a long so it puts a - when it's bad. */
304 #ifndef CPU_MULTI_FREQUENCY
307 ticks
= freq_sum
= 0;
309 tick_add_task(dbg_audio_task
);
312 screens
[i
].setfont(FONT_SYSFIXED
);
316 button
= get_action(CONTEXT_STD
,HZ
/5);
319 case ACTION_STD_NEXT
:
322 case ACTION_STD_PREV
:
325 case ACTION_STD_CANCEL
:
330 buffering_get_debugdata(&d
);
331 bufused
= bufsize
- pcmbuf_free();
336 screens
[i
].clear_display();
339 screens
[i
].putsf(0, line
++, "pcm: %6ld/%ld", (long) bufused
, (long) bufsize
);
341 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
342 bufsize
, 0, bufused
, HORIZONTAL
);
345 screens
[i
].putsf(0, line
++, "alloc: %6ld/%ld", audio_filebufused(),
348 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
349 if (screens
[i
].lcdheight
> 80)
351 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
352 filebuflen
, 0, audio_filebufused(), HORIZONTAL
);
355 screens
[i
].putsf(0, line
++, "real: %6ld/%ld", (long)d
.buffered_data
,
358 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
359 filebuflen
, 0, (long)d
.buffered_data
, HORIZONTAL
);
364 screens
[i
].putsf(0, line
++, "usefl: %6ld/%ld", (long)(d
.useful_data
),
367 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
368 if (screens
[i
].lcdheight
> 80)
370 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
371 filebuflen
, 0, d
.useful_data
, HORIZONTAL
);
376 screens
[i
].putsf(0, line
++, "data_rem: %ld", (long)d
.data_rem
);
378 screens
[i
].putsf(0, line
++, "track count: %2d", audio_track_count());
380 screens
[i
].putsf(0, line
++, "handle count: %d", (int)d
.num_handles
);
382 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
383 screens
[i
].putsf(0, line
++, "cpu freq: %3dMHz",
384 (int)((FREQ
+ 500000) / 1000000));
389 int avgclock
= freq_sum
* 10 / ticks
; /* in 100 kHz */
390 #ifdef CPU_MULTI_FREQUENCY
391 int boostquota
= (avgclock
* 100 - CPUFREQ_NORMAL
/1000) /
392 ((CPUFREQ_MAX
- CPUFREQ_NORMAL
) / 1000000); /* in 0.1 % */
394 int boostquota
= boost_ticks
* 1000 / ticks
; /* in 0.1 % */
396 screens
[i
].putsf(0, line
++, "boost:%3d.%d%% (%d.%dMHz)",
397 boostquota
/10, boostquota
%10, avgclock
/10, avgclock
%10);
400 screens
[i
].putsf(0, line
++, "pcmbufdesc: %2d/%2d",
401 pcmbuf_used_descs(), pcmbufdescs
);
402 screens
[i
].putsf(0, line
++, "watermark: %6d",
409 tick_remove_task(dbg_audio_task
);
412 screens
[i
].setfont(FONT_UI
);
416 #endif /* CONFIG_CODEC */
417 #endif /* HAVE_LCD_BITMAP */
419 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
420 static const char* dbg_partitions_getname(int selected_item
, void *data
,
421 char *buffer
, size_t buffer_len
)
424 int partition
= selected_item
/2;
425 struct partinfo
* p
= disk_partinfo(partition
);
428 snprintf(buffer
, buffer_len
, " T:%x %ld MB", p
->type
, p
->size
/ ( 2048 / ( SECTOR_SIZE
/ 512 )));
432 snprintf(buffer
, buffer_len
, "P%d: S:%lx", partition
, p
->start
);
437 bool dbg_partitions(void)
439 struct simplelist_info info
;
440 simplelist_info_init(&info
, "Partition Info", 4, NULL
);
441 info
.selection_size
= 2;
442 info
.hide_selection
= true;
443 info
.scroll_all
= true;
444 info
.get_name
= dbg_partitions_getname
;
445 return simplelist_show_list(&info
);
447 #endif /* PLATFORM_NATIVE */
449 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
450 static bool dbg_spdif(void)
453 unsigned int control
;
458 unsigned int interruptstat
;
459 bool valnogood
, symbolerr
, parityerr
;
462 int spdif_source
= spdif_get_output_source(&spdif_src_on
);
463 spdif_set_output_source(AUDIO_SRC_SPDIF
IF_SPDIF_POWER_(, true));
466 lcd_setfont(FONT_SYSFIXED
);
468 #ifdef HAVE_SPDIF_POWER
469 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
476 control
= EBU1RCVCCHANNEL1
;
477 interruptstat
= INTERRUPTSTAT
;
478 INTERRUPTCLEAR
= 0x03c00000;
480 valnogood
= (interruptstat
& 0x01000000)?true:false;
481 symbolerr
= (interruptstat
& 0x00800000)?true:false;
482 parityerr
= (interruptstat
& 0x00400000)?true:false;
484 lcd_putsf(0, line
++, "Val: %s Sym: %s Par: %s",
487 parityerr
?"--":"OK");
489 lcd_putsf(0, line
++, "Status word: %08x", (int)control
);
494 lcd_putsf(0, line
++, "PRO: %d (%s)",
495 x
, x
?"Professional":"Consumer");
497 x
= (control
>> 30) & 1;
498 lcd_putsf(0, line
++, "Audio: %d (%s)",
499 x
, x
?"Non-PCM":"PCM");
501 x
= (control
>> 29) & 1;
502 lcd_putsf(0, line
++, "Copy: %d (%s)",
503 x
, x
?"Permitted":"Inhibited");
505 x
= (control
>> 27) & 7;
518 lcd_putsf(0, line
++, "Preemphasis: %d (%s)", x
, s
);
520 x
= (control
>> 24) & 3;
521 lcd_putsf(0, line
++, "Mode: %d", x
);
523 category
= (control
>> 17) & 127;
535 lcd_putsf(0, line
++, "Category: 0x%02x (%s)", category
, s
);
537 x
= (control
>> 16) & 1;
539 if(((category
& 0x70) == 0x10) ||
540 ((category
& 0x70) == 0x40) ||
541 ((category
& 0x78) == 0x38))
543 generation
= !generation
;
545 lcd_putsf(0, line
++, "Generation: %d (%s)",
546 x
, generation
?"Original":"No ind.");
548 x
= (control
>> 12) & 15;
549 lcd_putsf(0, line
++, "Source: %d", x
);
552 x
= (control
>> 8) & 15;
568 lcd_putsf(0, line
++, "Channel: %d (%s)", x
, s
);
570 x
= (control
>> 4) & 15;
583 lcd_putsf(0, line
++, "Frequency: %d (%s)", x
, s
);
585 x
= (control
>> 2) & 3;
586 lcd_putsf(0, line
++, "Clock accuracy: %d", x
);
589 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
590 lcd_putsf(0, line
++, "Measured freq: %ldHz",
591 spdif_measure_frequency());
596 if (action_userabort(HZ
/10))
600 spdif_set_output_source(spdif_source
IF_SPDIF_POWER_(, spdif_src_on
));
602 #ifdef HAVE_SPDIF_POWER
603 spdif_power_enable(global_settings
.spdif_enable
);
606 lcd_setfont(FONT_UI
);
609 #endif /* CPU_COLDFIRE */
611 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
612 static bool dbg_pcf(void)
616 #ifdef HAVE_LCD_BITMAP
617 lcd_setfont(FONT_SYSFIXED
);
625 lcd_putsf(0, line
++, "DCDC1: %02x", pcf50605_read(0x1b));
626 lcd_putsf(0, line
++, "DCDC2: %02x", pcf50605_read(0x1c));
627 lcd_putsf(0, line
++, "DCDC3: %02x", pcf50605_read(0x1d));
628 lcd_putsf(0, line
++, "DCDC4: %02x", pcf50605_read(0x1e));
629 lcd_putsf(0, line
++, "DCDEC1: %02x", pcf50605_read(0x1f));
630 lcd_putsf(0, line
++, "DCDEC2: %02x", pcf50605_read(0x20));
631 lcd_putsf(0, line
++, "DCUDC1: %02x", pcf50605_read(0x21));
632 lcd_putsf(0, line
++, "DCUDC2: %02x", pcf50605_read(0x22));
633 lcd_putsf(0, line
++, "IOREGC: %02x", pcf50605_read(0x23));
634 lcd_putsf(0, line
++, "D1REGC: %02x", pcf50605_read(0x24));
635 lcd_putsf(0, line
++, "D2REGC: %02x", pcf50605_read(0x25));
636 lcd_putsf(0, line
++, "D3REGC: %02x", pcf50605_read(0x26));
637 lcd_putsf(0, line
++, "LPREG1: %02x", pcf50605_read(0x27));
639 if (button_get_w_tmo(HZ
/10) == (DEBUG_CANCEL
|BUTTON_REL
))
641 lcd_setfont(FONT_UI
);
646 lcd_setfont(FONT_UI
);
651 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
652 static bool dbg_cpufreq(void)
657 #ifdef HAVE_LCD_BITMAP
658 lcd_setfont(FONT_SYSFIXED
);
666 lcd_putsf(0, line
++, "Frequency: %ld", FREQ
);
667 lcd_putsf(0, line
++, "boost_counter: %d", get_cpu_boost_counter());
670 button
= get_action(CONTEXT_STD
,HZ
/10);
674 case ACTION_STD_PREV
:
678 case ACTION_STD_NEXT
:
683 while (get_cpu_boost_counter() > 0)
685 set_cpu_frequency(CPUFREQ_DEFAULT
);
688 case ACTION_STD_CANCEL
:
689 lcd_setfont(FONT_UI
);
693 lcd_setfont(FONT_UI
);
696 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
698 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
700 static const char* tsc2100_debug_getname(int selected_item
, void * data
,
701 char *buffer
, size_t buffer_len
)
703 int *page
= (int*)data
;
704 bool reserved
= false;
708 if ((selected_item
> 0x0a) ||
709 (selected_item
== 0x04) ||
710 (selected_item
== 0x08))
714 if ((selected_item
> 0x05) ||
715 (selected_item
== 0x02))
719 if (selected_item
> 0x1e)
724 snprintf(buffer
, buffer_len
, "%02x: RSVD", selected_item
);
726 snprintf(buffer
, buffer_len
, "%02x: %04x", selected_item
,
727 tsc2100_readreg(*page
, selected_item
)&0xffff);
730 static int tsc2100debug_action_callback(int action
, struct gui_synclist
*lists
)
732 int *page
= (int*)lists
->data
;
733 if (action
== ACTION_STD_OK
)
736 snprintf(lists
->title
, 32,
737 "tsc2100 registers - Page %d", *page
);
738 return ACTION_REDRAW
;
742 static bool tsc2100_debug(void)
745 char title
[32] = "tsc2100 registers - Page 0";
746 struct simplelist_info info
;
747 simplelist_info_init(&info
, title
, 32, &page
);
748 info
.timeout
= HZ
/100;
749 info
.get_name
= tsc2100_debug_getname
;
750 info
.action_callback
= tsc2100debug_action_callback
;
751 return simplelist_show_list(&info
);
754 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
755 #ifdef HAVE_LCD_BITMAP
757 * view_battery() shows a automatically scaled graph of the battery voltage
758 * over time. Usable for estimating battery life / charging rate.
759 * The power_history array is updated in power_thread of powermgmt.c.
762 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
763 #define BAT_YSPACE (LCD_HEIGHT - 20)
766 static bool view_battery(void)
769 int i
, x
, y
, y1
, y2
, grid
, graph
;
770 unsigned short maxv
, minv
;
772 lcd_setfont(FONT_SYSFIXED
);
778 case 0: /* voltage history graph */
779 /* Find maximum and minimum voltage for scaling */
780 minv
= power_history
[0];
782 for (i
= 1; i
< BAT_LAST_VAL
&& power_history
[i
]; i
++) {
783 if (power_history
[i
] > maxv
)
784 maxv
= power_history
[i
];
785 if (power_history
[i
] < minv
)
786 minv
= power_history
[i
];
789 /* adjust grid scale */
790 if ((maxv
- minv
) > 50)
796 lcd_putsf(0, 0, "battery %d.%03dV", power_history
[0] / 1000,
797 power_history
[0] % 1000);
798 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
799 minv
/ 1000, minv
% 1000, maxv
/ 1000, maxv
% 1000,
803 while ((y
= (minv
- (minv
% grid
)+i
*grid
)) < maxv
)
805 graph
= ((y
-minv
)*BAT_YSPACE
)/(maxv
-minv
);
806 graph
= LCD_HEIGHT
-1 - graph
;
808 /* draw dotted horizontal grid line */
809 for (x
=0; x
<LCD_WIDTH
;x
=x
+2)
810 lcd_drawpixel(x
,graph
);
816 /* draw plot of power history
819 for (i
= BAT_LAST_VAL
- 1; i
> 0; i
--)
821 if (power_history
[i
] && power_history
[i
-1])
823 y1
= (power_history
[i
] - minv
) * BAT_YSPACE
/
825 y1
= MIN(MAX(LCD_HEIGHT
-1 - y1
, 20),
827 y2
= (power_history
[i
-1] - minv
) * BAT_YSPACE
/
829 y2
= MIN(MAX(LCD_HEIGHT
-1 - y2
, 20),
832 lcd_set_drawmode(DRMODE_SOLID
);
834 /* make line thicker */
835 lcd_drawline(((x
*LCD_WIDTH
)/(BAT_LAST_VAL
)),
837 (((x
+1)*LCD_WIDTH
)/(BAT_LAST_VAL
)),
839 lcd_drawline(((x
*LCD_WIDTH
)/(BAT_LAST_VAL
))+1,
841 (((x
+1)*LCD_WIDTH
)/(BAT_LAST_VAL
))+1,
848 case 1: /* status: */
849 #if CONFIG_CHARGING >= CHARGING_MONITOR
850 lcd_putsf(0, 0, "Pwr status: %s",
851 charging_state() ? "charging" : "discharging");
853 lcd_puts(0, 0, "Power status:");
855 battery_read_info(&y
, NULL
);
856 lcd_putsf(0, 1, "Battery: %d.%03d V", y
/ 1000, y
% 1000);
858 y
= (adc_read(ADC_EXT_POWER
) * EXT_SCALE_FACTOR
) / 1000;
859 lcd_putsf(0, 2, "External: %d.%03d V", y
/ 1000, y
% 1000);
862 #if defined ARCHOS_RECORDER
863 lcd_putsf(0, 3, "Chgr: %s %s",
864 charger_inserted() ? "present" : "absent",
865 charger_enabled() ? "on" : "off");
866 lcd_putsf(0, 5, "short delta: %d", short_delta
);
867 lcd_putsf(0, 6, "long delta: %d", long_delta
);
868 lcd_puts(0, 7, power_message
);
869 lcd_putsf(0, 8, "USB Inserted: %s",
870 usb_inserted() ? "yes" : "no");
871 #elif defined IPOD_NANO || defined IPOD_VIDEO
872 int usb_pwr
= (GPIOL_INPUT_VAL
& 0x10)?true:false;
873 int ext_pwr
= (GPIOL_INPUT_VAL
& 0x08)?false:true;
874 int dock
= (GPIOA_INPUT_VAL
& 0x10)?true:false;
875 int charging
= (GPIOB_INPUT_VAL
& 0x01)?false:true;
876 int headphone
= (GPIOA_INPUT_VAL
& 0x80)?true:false;
878 lcd_putsf(0, 3, "USB pwr: %s",
879 usb_pwr
? "present" : "absent");
880 lcd_putsf(0, 4, "EXT pwr: %s",
881 ext_pwr
? "present" : "absent");
882 lcd_putsf(0, 5, "Battery: %s",
883 charging
? "charging" : (usb_pwr
||ext_pwr
) ? "charged" : "discharging");
884 lcd_putsf(0, 6, "Dock mode: %s",
885 dock
? "enabled" : "disabled");
886 lcd_putsf(0, 7, "Headphone: %s",
887 headphone
? "connected" : "disconnected");
889 if(probed_ramsize
== 64)
890 x
= (adc_read(ADC_4066_ISTAT
) * 2400) / (1024 * 2);
892 x
= (adc_read(ADC_4066_ISTAT
) * 2400) / (1024 * 3);
893 lcd_putsf(0, 8, "Ibat: %d mA", x
);
894 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x
* y
/ 1000);
896 #elif defined TOSHIBA_GIGABEAT_S
900 static const unsigned char * const chrgstate_strings
[] =
911 lcd_putsf(0, line
++, "Charger: %s",
912 charger_inserted() ? "present" : "absent");
914 st
= power_input_status() &
915 (POWER_INPUT_CHARGER
| POWER_INPUT_BATTERY
);
916 lcd_putsf(0, line
++, "%s%s",
917 (st
& POWER_INPUT_MAIN_CHARGER
) ? " Main" : "",
918 (st
& POWER_INPUT_USB_CHARGER
) ? " USB" : "");
920 y
= ARRAYLEN(chrgstate_strings
) - 1;
922 switch (charge_state
)
924 case CHARGE_STATE_DISABLED
: y
--;
925 case CHARGE_STATE_ERROR
: y
--;
926 case DISCHARGING
: y
--;
933 lcd_putsf(0, line
++, "State: %s", chrgstate_strings
[y
]);
935 lcd_putsf(0, line
++, "Battery Switch: %s",
936 (st
& POWER_INPUT_BATTERY
) ? "On" : "Off");
938 y
= chrgraw_adc_voltage();
939 lcd_putsf(0, line
++, "CHRGRAW: %d.%03d V",
942 y
= application_supply_adc_voltage();
943 lcd_putsf(0, line
++, "BP : %d.%03d V",
946 y
= battery_adc_charge_current();
947 if (y
< 0) x
= '-', y
= -y
;
949 lcd_putsf(0, line
++, "CHRGISN:%c%d mA", x
, y
);
951 y
= cccv_regulator_dissipation();
952 lcd_putsf(0, line
++, "P CCCV : %d mW", y
);
954 y
= battery_charge_current();
955 if (y
< 0) x
= '-', y
= -y
;
957 lcd_putsf(0, line
++, "I Charge:%c%d mA", x
, y
);
959 y
= battery_adc_temp();
962 lcd_putsf(0, line
++, "T Battery: %dC (%dF)", y
,
965 /* Conversion disabled */
966 lcd_puts(0, line
++, "T Battery: ?");
969 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
970 CONFIG_CPU == AS3525v2
971 static const char * const chrgstate_strings
[] =
973 [CHARGE_STATE_DISABLED
- CHARGE_STATE_DISABLED
]= "Disabled",
974 [CHARGE_STATE_ERROR
- CHARGE_STATE_DISABLED
] = "Error",
975 [DISCHARGING
- CHARGE_STATE_DISABLED
] = "Discharging",
976 [CHARGING
- CHARGE_STATE_DISABLED
] = "Charging",
978 const char *str
= NULL
;
980 lcd_putsf(0, 3, "Charger: %s",
981 charger_inserted() ? "present" : "absent");
983 y
= charge_state
- CHARGE_STATE_DISABLED
;
984 if ((unsigned)y
< ARRAYLEN(chrgstate_strings
))
985 str
= chrgstate_strings
[y
];
987 lcd_putsf(0, 4, "State: %s",
988 str
? str
: "<unknown>");
990 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
991 #elif defined(IPOD_NANO2G)
992 y
= pmu_read_battery_voltage();
993 lcd_putsf(17, 1, "RAW: %d.%03d V", y
/ 1000, y
% 1000);
994 y
= pmu_read_battery_current();
995 lcd_putsf(0, 2, "Battery current: %d mA", y
);
996 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON
, PWRCONEXT
);
997 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON
, CLKCON2
, CLKCON3
);
998 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS
, PLL1PMS
, PLL2PMS
);
999 x
= pmu_read(0x1b) & 0xf;
1000 y
= pmu_read(0x1a) * 25 + 625;
1001 lcd_putsf(0, 6, "AUTO: %x / %d mV", x
, y
);
1002 x
= pmu_read(0x1f) & 0xf;
1003 y
= pmu_read(0x1e) * 25 + 625;
1004 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x
, y
);
1005 x
= pmu_read(0x23) & 0xf;
1006 y
= pmu_read(0x22) * 25 + 625;
1007 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x
, y
);
1008 x
= pmu_read(0x27) & 0xf;
1009 y
= pmu_read(0x26) * 100 + 900;
1010 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x
, y
);
1011 for (i
= 0; i
< 6; i
++)
1013 x
= pmu_read(0x2e + (i
<< 1)) & 0xf;
1014 y
= pmu_read(0x2d + (i
<< 1)) * 100 + 900;
1015 lcd_putsf(0, 10 + i
, "LDO%d: %x / %d mV", i
+ 1, x
, y
);
1018 lcd_putsf(0, 3, "Charger: %s",
1019 charger_inserted() ? "present" : "absent");
1020 #endif /* target type */
1021 #endif /* CONFIG_CHARGING */
1024 case 2: /* voltage deltas: */
1025 lcd_puts(0, 0, "Voltage deltas:");
1027 for (i
= 0; i
<= 6; i
++) {
1028 y
= power_history
[i
] - power_history
[i
+1];
1029 lcd_putsf(0, i
+1, "-%d min: %s%d.%03d V", i
,
1030 (y
< 0) ? "-" : "", ((y
< 0) ? y
* -1 : y
) / 1000,
1031 ((y
< 0) ? y
* -1 : y
) % 1000);
1035 case 3: /* remaining time estimation: */
1037 #ifdef ARCHOS_RECORDER
1038 lcd_putsf(0, 0, "charge_state: %d", charge_state
);
1040 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min
);
1042 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level
);
1044 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p
, pid_i
);
1046 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec
);
1047 #endif /* ARCHOS_RECORDER */
1049 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1050 power_history
[0] / 1000,
1051 power_history
[0] % 1000);
1053 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1055 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1061 switch(get_action(CONTEXT_STD
,HZ
/2))
1063 case ACTION_STD_PREV
:
1068 case ACTION_STD_NEXT
:
1073 case ACTION_STD_CANCEL
:
1074 lcd_setfont(FONT_UI
);
1078 lcd_setfont(FONT_UI
);
1082 #endif /* HAVE_LCD_BITMAP */
1085 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1086 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1088 #if (CONFIG_STORAGE & STORAGE_MMC)
1089 #define CARDTYPE "MMC"
1090 #elif (CONFIG_STORAGE & STORAGE_SD)
1091 #define CARDTYPE "microSD"
1094 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1097 int *cardnum
= (int*)lists
->data
;
1098 unsigned char card_name
[6];
1099 unsigned char pbuf
[32];
1100 char *title
= lists
->title
;
1101 static const unsigned char i_vmin
[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1102 static const unsigned char i_vmax
[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1103 static const unsigned char * const kbit_units
[] = { "kBit/s", "MBit/s", "GBit/s" };
1104 static const unsigned char * const nsec_units
[] = { "ns", "µs", "ms" };
1105 #if (CONFIG_STORAGE & STORAGE_MMC)
1106 static const char * const mmc_spec_vers
[] = { "1.0-1.2", "1.4", "2.0-2.2",
1107 "3.1-3.31", "4.0" };
1110 if ((btn
== ACTION_STD_OK
) || (btn
== SYS_FS_CHANGED
) || (btn
== ACTION_REDRAW
))
1113 if (btn
== ACTION_STD_OK
)
1115 *cardnum
^= 0x1; /* change cards */
1119 simplelist_set_line_count(0);
1121 card
= card_get_info(*cardnum
);
1123 if (card
->initialized
> 0)
1126 for (i
=0; i
<sizeof(card_name
); i
++)
1128 card_name
[i
] = card_extract_bits(card
->cid
, (103-8*i
), 8);
1130 strlcpy(card_name
, card_name
, sizeof(card_name
));
1131 simplelist_addline(SIMPLELIST_ADD_LINE
,
1132 "%s Rev %d.%d", card_name
,
1133 (int) card_extract_bits(card
->cid
, 63, 4),
1134 (int) card_extract_bits(card
->cid
, 59, 4));
1135 simplelist_addline(SIMPLELIST_ADD_LINE
,
1137 #if (CONFIG_STORAGE & STORAGE_SD)
1138 (int) card_extract_bits(card
->cid
, 11, 4),
1139 (int) card_extract_bits(card
->cid
, 19, 8) + 2000
1140 #elif (CONFIG_STORAGE & STORAGE_MMC)
1141 (int) card_extract_bits(card
->cid
, 15, 4),
1142 (int) card_extract_bits(card
->cid
, 11, 4) + 1997
1145 simplelist_addline(SIMPLELIST_ADD_LINE
,
1146 #if (CONFIG_STORAGE & STORAGE_SD)
1148 card_extract_bits(card
->cid
, 55, 32)
1149 #elif (CONFIG_STORAGE & STORAGE_MMC)
1151 card_extract_bits(card
->cid
, 47, 16)
1155 simplelist_addline(SIMPLELIST_ADD_LINE
, "M=%02x, "
1156 #if (CONFIG_STORAGE & STORAGE_SD)
1158 (int) card_extract_bits(card
->cid
, 127, 8),
1159 card_extract_bits(card
->cid
, 119, 8),
1160 card_extract_bits(card
->cid
, 111, 8)
1161 #elif (CONFIG_STORAGE & STORAGE_MMC)
1163 (int) card_extract_bits(card
->cid
, 127, 8),
1164 (int) card_extract_bits(card
->cid
, 119, 16)
1168 #if (CONFIG_STORAGE & STORAGE_MMC)
1169 int temp
= card_extract_bits(card
->csd
, 125, 4);
1170 simplelist_addline(SIMPLELIST_ADD_LINE
,
1171 "MMC v%s", temp
< 5 ?
1172 mmc_spec_vers
[temp
] : "?.?");
1174 simplelist_addline(SIMPLELIST_ADD_LINE
,
1175 "Blocks: 0x%08lx", card
->numblocks
);
1176 output_dyn_value(pbuf
, sizeof pbuf
, card
->speed
/ 1000,
1178 simplelist_addline(SIMPLELIST_ADD_LINE
,
1180 output_dyn_value(pbuf
, sizeof pbuf
, card
->taac
,
1182 simplelist_addline(SIMPLELIST_ADD_LINE
,
1184 simplelist_addline(SIMPLELIST_ADD_LINE
,
1185 "Nsac: %d clk", card
->nsac
);
1186 simplelist_addline(SIMPLELIST_ADD_LINE
,
1187 "R2W: *%d", card
->r2w_factor
);
1188 #if (CONFIG_STORAGE & STORAGE_SD)
1189 int csd_structure
= card_extract_bits(card
->csd
, 127, 2);
1190 if (csd_structure
== 0) /* CSD version 1.0 */
1193 simplelist_addline(SIMPLELIST_ADD_LINE
,
1195 i_vmin
[card_extract_bits(card
->csd
, 61, 3)],
1196 i_vmax
[card_extract_bits(card
->csd
, 58, 3)]);
1197 simplelist_addline(SIMPLELIST_ADD_LINE
,
1199 i_vmin
[card_extract_bits(card
->csd
, 55, 3)],
1200 i_vmax
[card_extract_bits(card
->csd
, 52, 3)]);
1203 else if (card
->initialized
== 0)
1205 simplelist_addline(SIMPLELIST_ADD_LINE
, "Not Found!");
1207 #if (CONFIG_STORAGE & STORAGE_SD)
1208 else /* card->initialized < 0 */
1210 simplelist_addline(SIMPLELIST_ADD_LINE
, "Init Error! (%d)", card
->initialized
);
1213 snprintf(title
, 16, "[" CARDTYPE
" %d]", *cardnum
);
1214 gui_synclist_set_title(lists
, title
, Icon_NOICON
);
1215 gui_synclist_set_nb_items(lists
, simplelist_get_line_count());
1216 gui_synclist_select_item(lists
, 0);
1217 btn
= ACTION_REDRAW
;
1221 #elif (CONFIG_STORAGE & STORAGE_ATA)
1222 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1227 unsigned short* identify_info
= ata_get_identify();
1228 bool timing_info_present
= false;
1231 simplelist_set_line_count(0);
1233 for (i
=0; i
< 20; i
++)
1234 ((unsigned short*)buf
)[i
]=htobe16(identify_info
[i
+27]);
1236 /* kill trailing space */
1237 for (i
=39; i
&& buf
[i
]==' '; i
--)
1239 simplelist_addline(SIMPLELIST_ADD_LINE
, "Model: %s", buf
);
1240 for (i
=0; i
< 4; i
++)
1241 ((unsigned short*)buf
)[i
]=htobe16(identify_info
[i
+23]);
1243 simplelist_addline(SIMPLELIST_ADD_LINE
,
1244 "Firmware: %s", buf
);
1245 snprintf(buf
, sizeof buf
, "%ld MB",
1246 ((unsigned long)identify_info
[61] << 16 |
1247 (unsigned long)identify_info
[60]) / 2048 );
1248 simplelist_addline(SIMPLELIST_ADD_LINE
,
1251 fat_size( IF_MV2(0,) NULL
, &free
);
1252 simplelist_addline(SIMPLELIST_ADD_LINE
,
1253 "Free: %ld MB", free
/ 1024);
1254 simplelist_addline(SIMPLELIST_ADD_LINE
,
1255 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ
));
1256 i
= identify_info
[83] & (1<<3);
1257 simplelist_addline(SIMPLELIST_ADD_LINE
,
1258 "Power mgmt: %s", i
? "enabled" : "unsupported");
1259 i
= identify_info
[83] & (1<<9);
1260 simplelist_addline(SIMPLELIST_ADD_LINE
,
1261 "Noise mgmt: %s", i
? "enabled" : "unsupported");
1262 i
= identify_info
[82] & (1<<6);
1263 simplelist_addline(SIMPLELIST_ADD_LINE
,
1264 "Read-ahead: %s", i
? "enabled" : "unsupported");
1265 timing_info_present
= identify_info
[53] & (1<<1);
1266 if(timing_info_present
) {
1267 char pio3
[2], pio4
[2];pio3
[1] = 0;
1269 pio3
[0] = (identify_info
[64] & (1<<0)) ? '3' : 0;
1270 pio4
[0] = (identify_info
[64] & (1<<1)) ? '4' : 0;
1271 simplelist_addline(SIMPLELIST_ADD_LINE
,
1272 "PIO modes: 0 1 2 %s %s", pio3
, pio4
);
1275 simplelist_addline(SIMPLELIST_ADD_LINE
,
1276 "No PIO mode info");
1278 timing_info_present
= identify_info
[53] & (1<<1);
1279 if(timing_info_present
) {
1280 simplelist_addline(SIMPLELIST_ADD_LINE
,
1281 "Cycle times %dns/%dns",
1283 identify_info
[68] );
1285 simplelist_addline(SIMPLELIST_ADD_LINE
,
1288 int sector_size
= 512;
1289 if((identify_info
[106] & 0xe000) == 0x6000)
1290 sector_size
*= BIT_N(identify_info
[106] & 0x000f);
1291 simplelist_addline(SIMPLELIST_ADD_LINE
,
1292 "Physical sector size: %d", sector_size
);
1294 if (identify_info
[63] & (1<<0)) {
1295 char mdma0
[2], mdma1
[2], mdma2
[2];
1296 mdma0
[1] = mdma1
[1] = mdma2
[1] = 0;
1297 mdma0
[0] = (identify_info
[63] & (1<<0)) ? '0' : 0;
1298 mdma1
[0] = (identify_info
[63] & (1<<1)) ? '1' : 0;
1299 mdma2
[0] = (identify_info
[63] & (1<<2)) ? '2' : 0;
1300 simplelist_addline(SIMPLELIST_ADD_LINE
,
1301 "MDMA modes: %s %s %s", mdma0
, mdma1
, mdma2
);
1302 simplelist_addline(SIMPLELIST_ADD_LINE
,
1303 "MDMA Cycle times %dns/%dns",
1305 identify_info
[66] );
1308 simplelist_addline(SIMPLELIST_ADD_LINE
,
1309 "No MDMA mode info");
1311 if (identify_info
[53] & (1<<2)) {
1312 char udma0
[2], udma1
[2], udma2
[2], udma3
[2], udma4
[2], udma5
[2], udma6
[2];
1313 udma0
[1] = udma1
[1] = udma2
[1] = udma3
[1] = udma4
[1] = udma5
[1] = udma6
[1] = 0;
1314 udma0
[0] = (identify_info
[88] & (1<<0)) ? '0' : 0;
1315 udma1
[0] = (identify_info
[88] & (1<<1)) ? '1' : 0;
1316 udma2
[0] = (identify_info
[88] & (1<<2)) ? '2' : 0;
1317 udma3
[0] = (identify_info
[88] & (1<<3)) ? '3' : 0;
1318 udma4
[0] = (identify_info
[88] & (1<<4)) ? '4' : 0;
1319 udma5
[0] = (identify_info
[88] & (1<<5)) ? '5' : 0;
1320 udma6
[0] = (identify_info
[88] & (1<<6)) ? '6' : 0;
1321 simplelist_addline(SIMPLELIST_ADD_LINE
,
1322 "UDMA modes: %s %s %s %s %s %s %s", udma0
, udma1
, udma2
,
1323 udma3
, udma4
, udma5
, udma6
);
1326 simplelist_addline(SIMPLELIST_ADD_LINE
,
1327 "No UDMA mode info");
1329 #endif /* HAVE_ATA_DMA */
1330 timing_info_present
= identify_info
[53] & (1<<1);
1331 if(timing_info_present
) {
1332 i
= identify_info
[49] & (1<<11);
1333 simplelist_addline(SIMPLELIST_ADD_LINE
,
1334 "IORDY support: %s", i
? "yes" : "no");
1335 i
= identify_info
[49] & (1<<10);
1336 simplelist_addline(SIMPLELIST_ADD_LINE
,
1337 "IORDY disable: %s", i
? "yes" : "no");
1339 simplelist_addline(SIMPLELIST_ADD_LINE
,
1342 simplelist_addline(SIMPLELIST_ADD_LINE
,
1343 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1345 i
= ata_get_dma_mode();
1347 simplelist_addline(SIMPLELIST_ADD_LINE
,
1350 simplelist_addline(SIMPLELIST_ADD_LINE
,
1352 (i
& 0x40) ? "UDMA" : "MDMA",
1355 #endif /* HAVE_ATA_DMA */
1358 #else /* No SD, MMC or ATA */
1359 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1363 struct storage_info info
;
1364 storage_get_info(0,&info
);
1365 simplelist_addline(SIMPLELIST_ADD_LINE
, "Vendor: %s", info
.vendor
);
1366 simplelist_addline(SIMPLELIST_ADD_LINE
, "Model: %s", info
.product
);
1367 simplelist_addline(SIMPLELIST_ADD_LINE
, "Firmware: %s", info
.revision
);
1368 simplelist_addline(SIMPLELIST_ADD_LINE
,
1369 "Size: %ld MB", info
.num_sectors
*(info
.sector_size
/512)/2024);
1371 fat_size( IF_MV2(0,) NULL
, &free
);
1372 simplelist_addline(SIMPLELIST_ADD_LINE
,
1373 "Free: %ld MB", free
/ 1024);
1374 simplelist_addline(SIMPLELIST_ADD_LINE
,
1375 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1380 #if (CONFIG_STORAGE & STORAGE_ATA)
1381 static bool dbg_identify_info(void)
1383 int fd
= creat("/identify_info.bin", 0666);
1386 #ifdef ROCKBOX_LITTLE_ENDIAN
1387 ecwrite(fd
, ata_get_identify(), SECTOR_SIZE
/2, "s", true);
1389 write(fd
, ata_get_identify(), SECTOR_SIZE
);
1397 static bool dbg_disk_info(void)
1399 struct simplelist_info info
;
1400 simplelist_info_init(&info
, "Disk Info", 1, NULL
);
1401 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1404 info
.callback_data
= (void*)&card
;
1407 info
.action_callback
= disk_callback
;
1408 info
.hide_selection
= true;
1409 info
.scroll_all
= true;
1410 return simplelist_show_list(&info
);
1412 #endif /* PLATFORM_NATIVE */
1414 #ifdef HAVE_DIRCACHE
1415 static int dircache_callback(int btn
, struct gui_synclist
*lists
)
1417 (void)btn
; (void)lists
;
1418 simplelist_set_line_count(0);
1419 simplelist_addline(SIMPLELIST_ADD_LINE
, "Cache initialized: %s",
1420 dircache_is_enabled() ? "Yes" : "No");
1421 simplelist_addline(SIMPLELIST_ADD_LINE
, "Cache size: %d B",
1422 dircache_get_cache_size());
1423 simplelist_addline(SIMPLELIST_ADD_LINE
, "Last size: %d B",
1424 global_status
.dircache_size
);
1425 simplelist_addline(SIMPLELIST_ADD_LINE
, "Limit: %d B",
1427 simplelist_addline(SIMPLELIST_ADD_LINE
, "Reserve: %d/%d B",
1428 dircache_get_reserve_used(), DIRCACHE_RESERVE
);
1429 simplelist_addline(SIMPLELIST_ADD_LINE
, "Scanning took: %d s",
1430 dircache_get_build_ticks() / HZ
);
1431 simplelist_addline(SIMPLELIST_ADD_LINE
, "Entry count: %d",
1432 dircache_get_entry_count());
1436 static bool dbg_dircache_info(void)
1438 struct simplelist_info info
;
1439 simplelist_info_init(&info
, "Dircache Info", 7, NULL
);
1440 info
.action_callback
= dircache_callback
;
1441 info
.hide_selection
= true;
1442 info
.scroll_all
= true;
1443 return simplelist_show_list(&info
);
1446 #endif /* HAVE_DIRCACHE */
1448 #ifdef HAVE_TAGCACHE
1449 static int database_callback(int btn
, struct gui_synclist
*lists
)
1452 struct tagcache_stat
*stat
= tagcache_get_stat();
1453 static bool synced
= false;
1455 simplelist_set_line_count(0);
1457 simplelist_addline(SIMPLELIST_ADD_LINE
, "Initialized: %s",
1458 stat
->initialized
? "Yes" : "No");
1459 simplelist_addline(SIMPLELIST_ADD_LINE
, "DB Ready: %s",
1460 stat
->ready
? "Yes" : "No");
1461 simplelist_addline(SIMPLELIST_ADD_LINE
, "RAM Cache: %s",
1462 stat
->ramcache
? "Yes" : "No");
1463 simplelist_addline(SIMPLELIST_ADD_LINE
, "RAM: %d/%d B",
1464 stat
->ramcache_used
, stat
->ramcache_allocated
);
1465 simplelist_addline(SIMPLELIST_ADD_LINE
, "Progress: %d%% (%d entries)",
1466 stat
->progress
, stat
->processed_entries
);
1467 simplelist_addline(SIMPLELIST_ADD_LINE
, "Curfile: %s",
1468 stat
->curentry
? stat
->curentry
: "---");
1469 simplelist_addline(SIMPLELIST_ADD_LINE
, "Commit step: %d",
1471 simplelist_addline(SIMPLELIST_ADD_LINE
, "Commit delayed: %s",
1472 stat
->commit_delayed
? "Yes" : "No");
1474 simplelist_addline(SIMPLELIST_ADD_LINE
, "Queue length: %d",
1475 stat
->queue_length
);
1480 tagcache_screensync_event();
1483 if (!btn
&& stat
->curentry
)
1486 return ACTION_REDRAW
;
1489 if (btn
== ACTION_STD_CANCEL
)
1490 tagcache_screensync_enable(false);
1494 static bool dbg_tagcache_info(void)
1496 struct simplelist_info info
;
1497 simplelist_info_init(&info
, "Database Info", 8, NULL
);
1498 info
.action_callback
= database_callback
;
1499 info
.hide_selection
= true;
1500 info
.scroll_all
= true;
1502 /* Don't do nonblock here, must give enough processing time
1503 for tagcache thread. */
1504 /* info.timeout = TIMEOUT_NOBLOCK; */
1506 tagcache_screensync_enable(true);
1507 return simplelist_show_list(&info
);
1511 #if CONFIG_CPU == SH7034
1512 static bool dbg_save_roms(void)
1515 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
1517 fd
= creat("/internal_rom_0000-FFFF.bin", 0666);
1520 write(fd
, (void *)0, 0x10000);
1524 fd
= creat("/internal_rom_2000000-203FFFF.bin", 0666);
1527 write(fd
, (void *)0x2000000, 0x40000);
1531 system_memory_guard(oldmode
);
1534 #elif defined CPU_COLDFIRE
1535 static bool dbg_save_roms(void)
1538 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
1540 #if defined(IRIVER_H100_SERIES)
1541 fd
= creat("/internal_rom_000000-1FFFFF.bin", 0666);
1542 #elif defined(IRIVER_H300_SERIES)
1543 fd
= creat("/internal_rom_000000-3FFFFF.bin", 0666);
1544 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1545 fd
= creat("/internal_rom_000000-3FFFFF.bin", 0666);
1546 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1547 fd
= creat("/internal_rom_000000-1FFFFF.bin", 0666);
1551 write(fd
, (void *)0, FLASH_SIZE
);
1554 system_memory_guard(oldmode
);
1557 fd
= creat("/internal_eeprom.bin", 0666);
1561 char buf
[EEPROM_SIZE
];
1564 old_irq_level
= disable_irq_save();
1566 err
= eeprom_24cxx_read(0, buf
, sizeof buf
);
1568 restore_irq(old_irq_level
);
1571 splashf(HZ
*3, "Eeprom read failure (%d)", err
);
1574 write(fd
, buf
, sizeof buf
);
1583 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1584 static bool dbg_save_roms(void)
1588 fd
= creat("/internal_rom_000000-0FFFFF.bin", 0666);
1591 write(fd
, (void *)0x20000000, FLASH_SIZE
);
1597 #elif CONFIG_CPU == IMX31L
1598 static bool dbg_save_roms(void)
1602 fd
= creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1605 write(fd
, (void*)0xa0000000, FLASH_SIZE
);
1611 #elif defined(CPU_TCC780X)
1612 static bool dbg_save_roms(void)
1616 fd
= creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1619 write(fd
, (void*)0xe0000000, 0x2000);
1630 #ifdef CONFIG_TUNER_MULTI
1631 static int tuner_type
= 0;
1632 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1634 #define IF_TUNER_TYPE(type)
1637 static int radio_callback(int btn
, struct gui_synclist
*lists
)
1640 if (btn
== ACTION_STD_CANCEL
)
1642 simplelist_set_line_count(1);
1644 #if (CONFIG_TUNER & LV24020LP)
1645 simplelist_addline(SIMPLELIST_ADD_LINE
,
1646 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT
) );
1647 simplelist_addline(SIMPLELIST_ADD_LINE
,
1648 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT
) );
1649 simplelist_addline(SIMPLELIST_ADD_LINE
,
1650 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM
) );
1651 simplelist_addline(SIMPLELIST_ADD_LINE
,
1652 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF
) );
1653 simplelist_addline(SIMPLELIST_ADD_LINE
,
1654 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD
) );
1655 simplelist_addline(SIMPLELIST_ADD_LINE
,
1656 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET
) );
1657 simplelist_addline(SIMPLELIST_ADD_LINE
,
1658 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET
) );
1659 #endif /* LV24020LP */
1660 #if (CONFIG_TUNER & S1A0903X01)
1661 simplelist_addline(SIMPLELIST_ADD_LINE
,
1662 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL
));
1663 /* This one doesn't return dynamic data atm */
1664 #endif /* S1A0903X01 */
1665 #if (CONFIG_TUNER & TEA5767)
1666 struct tea5767_dbg_info nfo
;
1667 tea5767_dbg_info(&nfo
);
1668 simplelist_addline(SIMPLELIST_ADD_LINE
, "Philips regs:");
1669 simplelist_addline(SIMPLELIST_ADD_LINE
,
1670 " Read: %02X %02X %02X %02X %02X",
1671 (unsigned)nfo
.read_regs
[0], (unsigned)nfo
.read_regs
[1],
1672 (unsigned)nfo
.read_regs
[2], (unsigned)nfo
.read_regs
[3],
1673 (unsigned)nfo
.read_regs
[4]);
1674 simplelist_addline(SIMPLELIST_ADD_LINE
,
1675 " Write: %02X %02X %02X %02X %02X",
1676 (unsigned)nfo
.write_regs
[0], (unsigned)nfo
.write_regs
[1],
1677 (unsigned)nfo
.write_regs
[2], (unsigned)nfo
.write_regs
[3],
1678 (unsigned)nfo
.write_regs
[4]);
1679 #endif /* TEA5767 */
1680 #if (CONFIG_TUNER & SI4700)
1681 IF_TUNER_TYPE(SI4700
)
1683 struct si4700_dbg_info nfo
;
1685 si4700_dbg_info(&nfo
);
1686 simplelist_addline(SIMPLELIST_ADD_LINE
, "SI4700 regs:");
1687 for (i
= 0; i
< 16; i
+= 4) {
1688 simplelist_addline(SIMPLELIST_ADD_LINE
,"%02X: %04X %04X %04X %04X",
1689 i
, nfo
.regs
[i
], nfo
.regs
[i
+1], nfo
.regs
[i
+2], nfo
.regs
[i
+3]);
1693 #if (CONFIG_TUNER & RDA5802)
1694 IF_TUNER_TYPE(RDA5802
)
1696 struct rda5802_dbg_info nfo
;
1698 rda5802_dbg_info(&nfo
);
1699 simplelist_addline(SIMPLELIST_ADD_LINE
, "RDA5802 regs:");
1700 for (i
= 0; i
< 16; i
+= 4) {
1701 simplelist_addline(SIMPLELIST_ADD_LINE
,"%02X: %04X %04X %04X %04X",
1702 i
, nfo
.regs
[i
], nfo
.regs
[i
+1], nfo
.regs
[i
+2], nfo
.regs
[i
+3]);
1705 #endif /* RDA55802 */
1706 return ACTION_REDRAW
;
1708 static bool dbg_fm_radio(void)
1710 struct simplelist_info info
;
1711 #ifdef CONFIG_TUNER_MULTI
1712 tuner_type
= tuner_detect_type();
1714 info
.scroll_all
= true;
1715 simplelist_info_init(&info
, "FM Radio", 1, NULL
);
1716 simplelist_set_line_count(0);
1717 simplelist_addline(SIMPLELIST_ADD_LINE
, "HW detected: %s",
1718 radio_hardware_present() ? "yes" : "no");
1720 info
.action_callback
= radio_hardware_present()?radio_callback
: NULL
;
1721 info
.hide_selection
= true;
1722 return simplelist_show_list(&info
);
1724 #endif /* CONFIG_TUNER */
1725 #endif /* !SIMULATOR */
1727 #ifdef HAVE_LCD_BITMAP
1728 extern bool do_screendump_instead_of_usb
;
1730 static bool dbg_screendump(void)
1732 do_screendump_instead_of_usb
= !do_screendump_instead_of_usb
;
1733 splashf(HZ
, "Screendump %s",
1734 do_screendump_instead_of_usb
?"enabled":"disabled");
1737 #endif /* HAVE_LCD_BITMAP */
1739 extern bool write_metadata_log
;
1741 static bool dbg_metadatalog(void)
1743 write_metadata_log
= !write_metadata_log
;
1744 splashf(HZ
, "Metadata log %s",
1745 write_metadata_log
?"enabled":"disabled");
1749 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1750 static bool dbg_set_memory_guard(void)
1752 static const struct opt_items names
[MAXMEMGUARD
] = {
1754 { "Flash ROM writes", -1 },
1755 { "Zero area (all)", -1 }
1757 int mode
= system_memory_guard(MEMGUARD_KEEP
);
1759 set_option( "Catch mem accesses", &mode
, INT
, names
, MAXMEMGUARD
, NULL
);
1760 system_memory_guard(mode
);
1764 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1766 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
1767 static bool dbg_write_eeprom(void)
1772 char buf
[EEPROM_SIZE
];
1775 fd
= open("/internal_eeprom.bin", O_RDONLY
);
1779 rc
= read(fd
, buf
, EEPROM_SIZE
);
1781 if(rc
== EEPROM_SIZE
)
1783 old_irq_level
= disable_irq_save();
1785 err
= eeprom_24cxx_write(0, buf
, sizeof buf
);
1787 splashf(HZ
*3, "Eeprom write failure (%d)", err
);
1789 splash(HZ
*3, "Eeprom written successfully");
1791 restore_irq(old_irq_level
);
1795 splashf(HZ
*3, "File read error (%d)",rc
);
1801 splash(HZ
*3, "Failed to open 'internal_eeprom.bin'");
1806 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
1807 #ifdef CPU_BOOST_LOGGING
1808 static bool cpu_boost_log(void)
1811 int count
= cpu_boost_log_getcount();
1812 int lines
= LCD_HEIGHT
/SYSFONT_HEIGHT
;
1815 lcd_setfont(FONT_SYSFIXED
);
1816 str
= cpu_boost_log_getlog_first();
1819 lcd_clear_display();
1820 for(j
=0; j
<lines
; j
++,i
++)
1823 str
= cpu_boost_log_getlog_next();
1826 if(strlen(str
) > LCD_WIDTH
/SYSFONT_WIDTH
)
1827 lcd_puts_scroll(0, j
, str
);
1837 switch(get_action(CONTEXT_STD
,TIMEOUT_BLOCK
))
1840 case ACTION_STD_PREV
:
1841 case ACTION_STD_NEXT
:
1844 case ACTION_STD_CANCEL
:
1852 get_action(CONTEXT_STD
,TIMEOUT_BLOCK
);
1853 lcd_setfont(FONT_UI
);
1858 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
1859 && !defined(IPOD_MINI) && !defined(SIMULATOR))
1860 extern bool wheel_is_touched
;
1861 extern int old_wheel_value
;
1862 extern int new_wheel_value
;
1863 extern int wheel_delta
;
1864 extern unsigned int accumulated_wheel_delta
;
1865 extern unsigned int wheel_velocity
;
1867 static bool dbg_scrollwheel(void)
1871 lcd_setfont(FONT_SYSFIXED
);
1875 if (action_userabort(HZ
/10))
1878 lcd_clear_display();
1880 /* show internal variables of scrollwheel driver */
1881 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched
) ? "true" : "false");
1882 lcd_putsf(0, 1, "new position: %2d", new_wheel_value
);
1883 lcd_putsf(0, 2, "old position: %2d", old_wheel_value
);
1884 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta
);
1885 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta
);
1886 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity
);
1888 /* show effective accelerated scrollspeed */
1889 speed
= button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity
);
1890 lcd_putsf(0, 6, "accel. speed: %4d", speed
);
1894 lcd_setfont(FONT_UI
);
1899 #if defined (HAVE_USBSTACK)
1901 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
1902 static bool toggle_usb_core_driver(int driver
, char *msg
)
1904 bool enabled
= !usb_core_driver_enabled(driver
);
1906 usb_core_enable_driver(driver
,enabled
);
1907 splashf(HZ
, "%s %s", msg
, enabled
?"enabled":"disabled");
1912 static bool toggle_usb_serial(void)
1914 return toggle_usb_core_driver(USB_DRIVER_SERIAL
,"USB Serial");
1920 #if CONFIG_USBOTG == USBOTG_ISP1583
1921 extern int dbg_usb_num_items(void);
1922 extern const char* dbg_usb_item(int selected_item
, void *data
,
1923 char *buffer
, size_t buffer_len
);
1925 static int isp1583_action_callback(int action
, struct gui_synclist
*lists
)
1928 if (action
== ACTION_NONE
)
1929 action
= ACTION_REDRAW
;
1933 static bool dbg_isp1583(void)
1935 struct simplelist_info isp1583
;
1936 isp1583
.scroll_all
= true;
1937 simplelist_info_init(&isp1583
, "ISP1583", dbg_usb_num_items(), NULL
);
1938 isp1583
.timeout
= HZ
/100;
1939 isp1583
.hide_selection
= true;
1940 isp1583
.get_name
= dbg_usb_item
;
1941 isp1583
.action_callback
= isp1583_action_callback
;
1942 return simplelist_show_list(&isp1583
);
1946 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
1947 extern int pic_dbg_num_items(void);
1948 extern const char* pic_dbg_item(int selected_item
, void *data
,
1949 char *buffer
, size_t buffer_len
);
1951 static int pic_action_callback(int action
, struct gui_synclist
*lists
)
1954 if (action
== ACTION_NONE
)
1955 action
= ACTION_REDRAW
;
1959 static bool dbg_pic(void)
1961 struct simplelist_info pic
;
1962 pic
.scroll_all
= true;
1963 simplelist_info_init(&pic
, "PIC", pic_dbg_num_items(), NULL
);
1964 pic
.timeout
= HZ
/100;
1965 pic
.hide_selection
= true;
1966 pic
.get_name
= pic_dbg_item
;
1967 pic
.action_callback
= pic_action_callback
;
1968 return simplelist_show_list(&pic
);
1973 /****** The menu *********/
1974 struct the_menu_item
{
1975 unsigned char *desc
; /* string or ID */
1976 bool (*function
) (void); /* return true if USB was connected */
1978 static const struct the_menu_item menuitems
[] = {
1979 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
1980 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
1981 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
1982 { "Dump ROM contents", dbg_save_roms
},
1984 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
1985 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
1986 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
1987 { "View I/O ports", dbg_ports
},
1989 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1990 { "View PCF registers", dbg_pcf
},
1992 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1993 { "TSC2100 debug", tsc2100_debug
},
1995 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1996 { "CPU frequency", dbg_cpufreq
},
1998 #if CONFIG_CPU == IMX31L
1999 { "DVFS/DPTC", __dbg_dvfs_dptc
},
2001 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2002 { "S/PDIF analyzer", dbg_spdif
},
2004 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2005 { "Catch mem accesses", dbg_set_memory_guard
},
2007 { "View OS stacks", dbg_os
},
2008 #ifdef HAVE_LCD_BITMAP
2009 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2010 { "View battery", view_battery
},
2012 { "Screendump", dbg_screendump
},
2014 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2015 { "View HW info", dbg_hw_info
},
2017 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2018 { "View partitions", dbg_partitions
},
2020 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2021 { "View disk info", dbg_disk_info
},
2022 #if (CONFIG_STORAGE & STORAGE_ATA)
2023 { "Dump ATA identify info", dbg_identify_info
},
2026 { "Metadata log", dbg_metadatalog
},
2027 #ifdef HAVE_DIRCACHE
2028 { "View dircache info", dbg_dircache_info
},
2030 #ifdef HAVE_TAGCACHE
2031 { "View database info", dbg_tagcache_info
},
2033 #ifdef HAVE_LCD_BITMAP
2034 #if CONFIG_CODEC == SWCODEC
2035 { "View buffering thread", dbg_buffering_thread
},
2036 #elif !defined(SIMULATOR)
2037 { "View audio thread", dbg_audio_thread
},
2040 { "pm histogram", peak_meter_histogram
},
2041 #endif /* PM_DEBUG */
2042 #endif /* HAVE_LCD_BITMAP */
2045 { "FM Radio", dbg_fm_radio
},
2048 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2049 { "Write back EEPROM", dbg_write_eeprom
},
2051 #if CONFIG_USBOTG == USBOTG_ISP1583
2052 { "View ISP1583 info", dbg_isp1583
},
2054 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2055 { "View PIC info", dbg_pic
},
2057 #ifdef ROCKBOX_HAS_LOGF
2058 {"Show Log File", logfdisplay
},
2059 {"Dump Log File", logfdump
},
2061 #if defined(HAVE_USBSTACK)
2062 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2063 {"USB Serial driver (logf)", toggle_usb_serial
},
2065 #endif /* HAVE_USBSTACK */
2066 #ifdef CPU_BOOST_LOGGING
2067 {"cpu_boost log",cpu_boost_log
},
2069 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2070 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2071 {"Debug scrollwheel", dbg_scrollwheel
},
2074 static int menu_action_callback(int btn
, struct gui_synclist
*lists
)
2077 if (btn
== ACTION_STD_OK
)
2080 viewportmanager_theme_enable(i
, false, NULL
);
2081 menuitems
[gui_synclist_get_sel_pos(lists
)].function();
2082 btn
= ACTION_REDRAW
;
2084 viewportmanager_theme_undo(i
, false);
2089 static const char* dbg_menu_getname(int item
, void * data
,
2090 char *buffer
, size_t buffer_len
)
2092 (void)data
; (void)buffer
; (void)buffer_len
;
2093 return menuitems
[item
].desc
;
2096 bool debug_menu(void)
2098 struct simplelist_info info
;
2100 simplelist_info_init(&info
, "Debug Menu", ARRAYLEN(menuitems
), NULL
);
2101 info
.action_callback
= menu_action_callback
;
2102 info
.get_name
= dbg_menu_getname
;
2103 return simplelist_show_list(&info
);