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 #include "core_alloc.h"
83 #if CONFIG_CODEC == SWCODEC
85 #include "buffering.h"
87 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
91 #ifdef IRIVER_H300_SERIES
92 #include "pcf50606.h" /* for pcf50606_read */
99 #if CONFIG_RTC == RTC_PCF50605
100 #include "pcf50605.h"
102 #include "appevents.h"
103 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
104 #include "debug-target.h"
107 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
108 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
109 || CONFIG_CPU == AS3525v2
115 #include "pmu-target.h"
119 #include "usb_core.h"
122 #if defined(IPOD_ACCESSORY_PROTOCOL)
126 /*---------------------------------------------------*/
127 /* SPECIAL DEBUG STUFF */
128 /*---------------------------------------------------*/
129 extern struct thread_entry threads
[MAXTHREADS
];
131 static char thread_status_char(unsigned status
)
133 static const char thread_status_chars
[THREAD_NUM_STATES
+1] =
135 [0 ... THREAD_NUM_STATES
] = '?',
136 [STATE_RUNNING
] = 'R',
137 [STATE_BLOCKED
] = 'B',
138 [STATE_SLEEPING
] = 'S',
139 [STATE_BLOCKED_W_TMO
] = 'T',
140 [STATE_FROZEN
] = 'F',
141 [STATE_KILLED
] = 'K',
144 if (status
> THREAD_NUM_STATES
)
145 status
= THREAD_NUM_STATES
;
147 return thread_status_chars
[status
];
150 static const char* threads_getname(int selected_item
, void *data
,
151 char *buffer
, size_t buffer_len
)
154 struct thread_entry
*thread
;
158 if (selected_item
< (int)NUM_CORES
)
160 snprintf(buffer
, buffer_len
, "Idle (%d): %2d%%", selected_item
,
161 idle_stack_usage(selected_item
));
165 selected_item
-= NUM_CORES
;
168 thread
= &threads
[selected_item
];
170 if (thread
->state
== STATE_KILLED
)
172 snprintf(buffer
, buffer_len
, "%2d: ---", selected_item
);
176 thread_get_name(name
, 32, thread
);
178 snprintf(buffer
, buffer_len
,
179 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
181 IF_COP(thread
->core
,)
182 #ifdef HAVE_SCHEDULER_BOOSTCTRL
183 (thread
->cpu_boost
) ? '+' :
185 ((thread
->state
== STATE_RUNNING
) ? '*' : ' '),
186 thread_status_char(thread
->state
),
187 IF_PRIO(thread
->base_priority
, thread
->priority
, )
188 thread_stack_usage(thread
), name
);
193 static int dbg_threads_action_callback(int action
, struct gui_synclist
*lists
)
196 #ifdef ROCKBOX_HAS_LOGF
197 if (action
== ACTION_STD_OK
)
199 int selpos
= gui_synclist_get_sel_pos(lists
);
201 if (selpos
>= NUM_CORES
)
202 remove_thread(threads
[selpos
- NUM_CORES
].id
);
204 remove_thread(threads
[selpos
].id
);
206 return ACTION_REDRAW
;
208 #endif /* ROCKBOX_HAS_LOGF */
209 if (action
== ACTION_NONE
)
210 action
= ACTION_REDRAW
;
214 static bool dbg_os(void)
216 struct simplelist_info info
;
217 simplelist_info_init(&info
, IF_COP("Core and ") "Stack usage:",
221 MAXTHREADS
+NUM_CORES
,
224 #ifndef ROCKBOX_HAS_LOGF
225 info
.hide_selection
= true;
226 info
.scroll_all
= true;
228 info
.action_callback
= dbg_threads_action_callback
;
229 info
.get_name
= threads_getname
;
230 return simplelist_show_list(&info
);
233 #ifdef HAVE_LCD_BITMAP
234 #if CONFIG_CODEC != SWCODEC
236 static bool dbg_audio_thread(void)
238 struct audio_debug d
;
240 lcd_setfont(FONT_SYSFIXED
);
244 if (action_userabort(HZ
/5))
247 audio_get_debugdata(&d
);
251 lcd_putsf(0, 0, "read: %x", d
.audiobuf_read
);
252 lcd_putsf(0, 1, "write: %x", d
.audiobuf_write
);
253 lcd_putsf(0, 2, "swap: %x", d
.audiobuf_swapwrite
);
254 lcd_putsf(0, 3, "playing: %d", d
.playing
);
255 lcd_putsf(0, 4, "playable: %x", d
.playable_space
);
256 lcd_putsf(0, 5, "unswapped: %x", d
.unswapped_space
);
258 /* Playable space left */
259 gui_scrollbar_draw(&screens
[SCREEN_MAIN
],0, 6*8, 112, 4, d
.audiobuflen
, 0,
260 d
.playable_space
, HORIZONTAL
);
262 /* Show the watermark limit */
263 gui_scrollbar_draw(&screens
[SCREEN_MAIN
],0, 6*8+4, 112, 4, d
.audiobuflen
, 0,
264 d
.low_watermark_level
, HORIZONTAL
);
266 lcd_putsf(0, 7, "wm: %x - %x",
267 d
.low_watermark_level
, d
.lowest_watermark_level
);
271 lcd_setfont(FONT_UI
);
274 #endif /* !SIMULATOR */
275 #else /* CONFIG_CODEC == SWCODEC */
276 static unsigned int ticks
, freq_sum
;
277 #ifndef CPU_MULTI_FREQUENCY
278 static unsigned int boost_ticks
;
281 static void dbg_audio_task(void)
283 #ifdef CPUFREQ_NORMAL
284 #ifndef CPU_MULTI_FREQUENCY
285 if(FREQ
> CPUFREQ_NORMAL
)
288 freq_sum
+= FREQ
/1000000; /* in MHz */
293 static bool dbg_buffering_thread(void)
299 size_t bufsize
= pcmbuf_get_bufsize();
300 int pcmbufdescs
= pcmbuf_descs();
301 struct buffering_debug d
;
302 size_t filebuflen
= audio_get_filebuflen();
303 /* This is a size_t, but call it a long so it puts a - when it's bad. */
305 #ifndef CPU_MULTI_FREQUENCY
308 ticks
= freq_sum
= 0;
310 tick_add_task(dbg_audio_task
);
313 screens
[i
].setfont(FONT_SYSFIXED
);
317 button
= get_action(CONTEXT_STD
,HZ
/5);
320 case ACTION_STD_NEXT
:
323 case ACTION_STD_PREV
:
326 case ACTION_STD_CANCEL
:
331 buffering_get_debugdata(&d
);
332 bufused
= bufsize
- pcmbuf_free();
337 screens
[i
].clear_display();
340 screens
[i
].putsf(0, line
++, "pcm: %6ld/%ld", (long) bufused
, (long) bufsize
);
342 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
343 bufsize
, 0, bufused
, HORIZONTAL
);
346 screens
[i
].putsf(0, line
++, "alloc: %6ld/%ld", audio_filebufused(),
349 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
350 if (screens
[i
].lcdheight
> 80)
352 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
353 filebuflen
, 0, audio_filebufused(), HORIZONTAL
);
356 screens
[i
].putsf(0, line
++, "real: %6ld/%ld", (long)d
.buffered_data
,
359 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
360 filebuflen
, 0, (long)d
.buffered_data
, HORIZONTAL
);
365 screens
[i
].putsf(0, line
++, "usefl: %6ld/%ld", (long)(d
.useful_data
),
368 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
369 if (screens
[i
].lcdheight
> 80)
371 gui_scrollbar_draw(&screens
[i
],0, line
*8, screens
[i
].lcdwidth
, 6,
372 filebuflen
, 0, d
.useful_data
, HORIZONTAL
);
377 screens
[i
].putsf(0, line
++, "data_rem: %ld", (long)d
.data_rem
);
379 screens
[i
].putsf(0, line
++, "track count: %2d", audio_track_count());
381 screens
[i
].putsf(0, line
++, "handle count: %d", (int)d
.num_handles
);
383 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
384 screens
[i
].putsf(0, line
++, "cpu freq: %3dMHz",
385 (int)((FREQ
+ 500000) / 1000000));
390 int avgclock
= freq_sum
* 10 / ticks
; /* in 100 kHz */
391 #ifdef CPU_MULTI_FREQUENCY
392 int boostquota
= (avgclock
* 100 - CPUFREQ_NORMAL
/1000) /
393 ((CPUFREQ_MAX
- CPUFREQ_NORMAL
) / 1000000); /* in 0.1 % */
395 int boostquota
= boost_ticks
* 1000 / ticks
; /* in 0.1 % */
397 screens
[i
].putsf(0, line
++, "boost:%3d.%d%% (%d.%dMHz)",
398 boostquota
/10, boostquota
%10, avgclock
/10, avgclock
%10);
401 screens
[i
].putsf(0, line
++, "pcmbufdesc: %2d/%2d",
402 pcmbuf_used_descs(), pcmbufdescs
);
403 screens
[i
].putsf(0, line
++, "watermark: %6d",
410 tick_remove_task(dbg_audio_task
);
413 screens
[i
].setfont(FONT_UI
);
417 #endif /* CONFIG_CODEC */
418 #endif /* HAVE_LCD_BITMAP */
420 static const char* bf_getname(int selected_item
, void *data
,
421 char *buffer
, size_t buffer_len
)
424 core_print_block_at(selected_item
, buffer
, buffer_len
);
428 static int bf_action_cb(int action
, struct gui_synclist
* list
)
430 if (action
== ACTION_STD_OK
)
432 if (gui_synclist_get_sel_pos(list
) == 0 && core_test_free())
434 splash(HZ
, "Freed test handle. New alloc should trigger compact");
438 splash(HZ
/1, "Attempting a 64k allocation");
439 int handle
= core_alloc("test", 64<<10);
440 splash(HZ
/2, (handle
> 0) ? "Success":"Fail");
441 /* for some reason simplelist doesn't allow adding items here if
442 * info.get_name is given, so use normal list api */
443 gui_synclist_set_nb_items(list
, core_get_num_blocks());
447 action
= ACTION_REDRAW
;
449 else if (action
== ACTION_NONE
)
450 action
= ACTION_REDRAW
;
454 static bool dbg_buflib_allocs(void)
456 struct simplelist_info info
;
457 simplelist_info_init(&info
, "mem allocs", core_get_num_blocks(), NULL
);
458 info
.get_name
= bf_getname
;
459 info
.action_callback
= bf_action_cb
;
460 info
.timeout
= TIMEOUT_BLOCK
;
461 return simplelist_show_list(&info
);
464 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
465 static const char* dbg_partitions_getname(int selected_item
, void *data
,
466 char *buffer
, size_t buffer_len
)
469 int partition
= selected_item
/2;
470 struct partinfo
* p
= disk_partinfo(partition
);
473 snprintf(buffer
, buffer_len
, " T:%x %ld MB", p
->type
, p
->size
/ ( 2048 / ( SECTOR_SIZE
/ 512 )));
477 snprintf(buffer
, buffer_len
, "P%d: S:%lx", partition
, p
->start
);
482 bool dbg_partitions(void)
484 struct simplelist_info info
;
485 simplelist_info_init(&info
, "Partition Info", 4, NULL
);
486 info
.selection_size
= 2;
487 info
.hide_selection
= true;
488 info
.scroll_all
= true;
489 info
.get_name
= dbg_partitions_getname
;
490 return simplelist_show_list(&info
);
492 #endif /* PLATFORM_NATIVE */
494 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
495 static bool dbg_spdif(void)
498 unsigned int control
;
503 unsigned int interruptstat
;
504 bool valnogood
, symbolerr
, parityerr
;
507 int spdif_source
= spdif_get_output_source(&spdif_src_on
);
508 spdif_set_output_source(AUDIO_SRC_SPDIF
IF_SPDIF_POWER_(, true));
511 lcd_setfont(FONT_SYSFIXED
);
513 #ifdef HAVE_SPDIF_POWER
514 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
521 control
= EBU1RCVCCHANNEL1
;
522 interruptstat
= INTERRUPTSTAT
;
523 INTERRUPTCLEAR
= 0x03c00000;
525 valnogood
= (interruptstat
& 0x01000000)?true:false;
526 symbolerr
= (interruptstat
& 0x00800000)?true:false;
527 parityerr
= (interruptstat
& 0x00400000)?true:false;
529 lcd_putsf(0, line
++, "Val: %s Sym: %s Par: %s",
532 parityerr
?"--":"OK");
534 lcd_putsf(0, line
++, "Status word: %08x", (int)control
);
539 lcd_putsf(0, line
++, "PRO: %d (%s)",
540 x
, x
?"Professional":"Consumer");
542 x
= (control
>> 30) & 1;
543 lcd_putsf(0, line
++, "Audio: %d (%s)",
544 x
, x
?"Non-PCM":"PCM");
546 x
= (control
>> 29) & 1;
547 lcd_putsf(0, line
++, "Copy: %d (%s)",
548 x
, x
?"Permitted":"Inhibited");
550 x
= (control
>> 27) & 7;
563 lcd_putsf(0, line
++, "Preemphasis: %d (%s)", x
, s
);
565 x
= (control
>> 24) & 3;
566 lcd_putsf(0, line
++, "Mode: %d", x
);
568 category
= (control
>> 17) & 127;
580 lcd_putsf(0, line
++, "Category: 0x%02x (%s)", category
, s
);
582 x
= (control
>> 16) & 1;
584 if(((category
& 0x70) == 0x10) ||
585 ((category
& 0x70) == 0x40) ||
586 ((category
& 0x78) == 0x38))
588 generation
= !generation
;
590 lcd_putsf(0, line
++, "Generation: %d (%s)",
591 x
, generation
?"Original":"No ind.");
593 x
= (control
>> 12) & 15;
594 lcd_putsf(0, line
++, "Source: %d", x
);
597 x
= (control
>> 8) & 15;
613 lcd_putsf(0, line
++, "Channel: %d (%s)", x
, s
);
615 x
= (control
>> 4) & 15;
628 lcd_putsf(0, line
++, "Frequency: %d (%s)", x
, s
);
630 x
= (control
>> 2) & 3;
631 lcd_putsf(0, line
++, "Clock accuracy: %d", x
);
634 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
635 lcd_putsf(0, line
++, "Measured freq: %ldHz",
636 spdif_measure_frequency());
641 if (action_userabort(HZ
/10))
645 spdif_set_output_source(spdif_source
IF_SPDIF_POWER_(, spdif_src_on
));
647 #ifdef HAVE_SPDIF_POWER
648 spdif_power_enable(global_settings
.spdif_enable
);
651 lcd_setfont(FONT_UI
);
654 #endif /* CPU_COLDFIRE */
656 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
657 static bool dbg_pcf(void)
661 #ifdef HAVE_LCD_BITMAP
662 lcd_setfont(FONT_SYSFIXED
);
670 lcd_putsf(0, line
++, "DCDC1: %02x", pcf50605_read(0x1b));
671 lcd_putsf(0, line
++, "DCDC2: %02x", pcf50605_read(0x1c));
672 lcd_putsf(0, line
++, "DCDC3: %02x", pcf50605_read(0x1d));
673 lcd_putsf(0, line
++, "DCDC4: %02x", pcf50605_read(0x1e));
674 lcd_putsf(0, line
++, "DCDEC1: %02x", pcf50605_read(0x1f));
675 lcd_putsf(0, line
++, "DCDEC2: %02x", pcf50605_read(0x20));
676 lcd_putsf(0, line
++, "DCUDC1: %02x", pcf50605_read(0x21));
677 lcd_putsf(0, line
++, "DCUDC2: %02x", pcf50605_read(0x22));
678 lcd_putsf(0, line
++, "IOREGC: %02x", pcf50605_read(0x23));
679 lcd_putsf(0, line
++, "D1REGC: %02x", pcf50605_read(0x24));
680 lcd_putsf(0, line
++, "D2REGC: %02x", pcf50605_read(0x25));
681 lcd_putsf(0, line
++, "D3REGC: %02x", pcf50605_read(0x26));
682 lcd_putsf(0, line
++, "LPREG1: %02x", pcf50605_read(0x27));
684 if (button_get_w_tmo(HZ
/10) == (DEBUG_CANCEL
|BUTTON_REL
))
686 lcd_setfont(FONT_UI
);
691 lcd_setfont(FONT_UI
);
696 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
697 static bool dbg_cpufreq(void)
702 #ifdef HAVE_LCD_BITMAP
703 lcd_setfont(FONT_SYSFIXED
);
711 lcd_putsf(0, line
++, "Frequency: %ld", FREQ
);
712 lcd_putsf(0, line
++, "boost_counter: %d", get_cpu_boost_counter());
715 button
= get_action(CONTEXT_STD
,HZ
/10);
719 case ACTION_STD_PREV
:
723 case ACTION_STD_NEXT
:
728 while (get_cpu_boost_counter() > 0)
730 set_cpu_frequency(CPUFREQ_DEFAULT
);
733 case ACTION_STD_CANCEL
:
734 lcd_setfont(FONT_UI
);
738 lcd_setfont(FONT_UI
);
741 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
743 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
745 static const char* tsc2100_debug_getname(int selected_item
, void * data
,
746 char *buffer
, size_t buffer_len
)
748 int *page
= (int*)data
;
749 bool reserved
= false;
753 if ((selected_item
> 0x0a) ||
754 (selected_item
== 0x04) ||
755 (selected_item
== 0x08))
759 if ((selected_item
> 0x05) ||
760 (selected_item
== 0x02))
764 if (selected_item
> 0x1e)
769 snprintf(buffer
, buffer_len
, "%02x: RSVD", selected_item
);
771 snprintf(buffer
, buffer_len
, "%02x: %04x", selected_item
,
772 tsc2100_readreg(*page
, selected_item
)&0xffff);
775 static int tsc2100debug_action_callback(int action
, struct gui_synclist
*lists
)
777 int *page
= (int*)lists
->data
;
778 if (action
== ACTION_STD_OK
)
781 snprintf(lists
->title
, 32,
782 "tsc2100 registers - Page %d", *page
);
783 return ACTION_REDRAW
;
787 static bool tsc2100_debug(void)
790 char title
[32] = "tsc2100 registers - Page 0";
791 struct simplelist_info info
;
792 simplelist_info_init(&info
, title
, 32, &page
);
793 info
.timeout
= HZ
/100;
794 info
.get_name
= tsc2100_debug_getname
;
795 info
.action_callback
= tsc2100debug_action_callback
;
796 return simplelist_show_list(&info
);
799 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
800 #ifdef HAVE_LCD_BITMAP
802 * view_battery() shows a automatically scaled graph of the battery voltage
803 * over time. Usable for estimating battery life / charging rate.
804 * The power_history array is updated in power_thread of powermgmt.c.
807 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
808 #define BAT_YSPACE (LCD_HEIGHT - 20)
811 static bool view_battery(void)
814 int i
, x
, y
, y1
, y2
, grid
, graph
;
815 unsigned short maxv
, minv
;
817 lcd_setfont(FONT_SYSFIXED
);
823 case 0: /* voltage history graph */
824 /* Find maximum and minimum voltage for scaling */
825 minv
= power_history
[0];
827 for (i
= 1; i
< BAT_LAST_VAL
&& power_history
[i
]; i
++) {
828 if (power_history
[i
] > maxv
)
829 maxv
= power_history
[i
];
830 if (power_history
[i
] < minv
)
831 minv
= power_history
[i
];
834 /* adjust grid scale */
835 if ((maxv
- minv
) > 50)
841 lcd_putsf(0, 0, "battery %d.%03dV", power_history
[0] / 1000,
842 power_history
[0] % 1000);
843 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
844 minv
/ 1000, minv
% 1000, maxv
/ 1000, maxv
% 1000,
848 while ((y
= (minv
- (minv
% grid
)+i
*grid
)) < maxv
)
850 graph
= ((y
-minv
)*BAT_YSPACE
)/(maxv
-minv
);
851 graph
= LCD_HEIGHT
-1 - graph
;
853 /* draw dotted horizontal grid line */
854 for (x
=0; x
<LCD_WIDTH
;x
=x
+2)
855 lcd_drawpixel(x
,graph
);
861 /* draw plot of power history
864 for (i
= BAT_LAST_VAL
- 1; i
> 0; i
--)
866 if (power_history
[i
] && power_history
[i
-1])
868 y1
= (power_history
[i
] - minv
) * BAT_YSPACE
/
870 y1
= MIN(MAX(LCD_HEIGHT
-1 - y1
, 20),
872 y2
= (power_history
[i
-1] - minv
) * BAT_YSPACE
/
874 y2
= MIN(MAX(LCD_HEIGHT
-1 - y2
, 20),
877 lcd_set_drawmode(DRMODE_SOLID
);
879 /* make line thicker */
880 lcd_drawline(((x
*LCD_WIDTH
)/(BAT_LAST_VAL
)),
882 (((x
+1)*LCD_WIDTH
)/(BAT_LAST_VAL
)),
884 lcd_drawline(((x
*LCD_WIDTH
)/(BAT_LAST_VAL
))+1,
886 (((x
+1)*LCD_WIDTH
)/(BAT_LAST_VAL
))+1,
893 case 1: /* status: */
894 #if CONFIG_CHARGING >= CHARGING_MONITOR
895 lcd_putsf(0, 0, "Pwr status: %s",
896 charging_state() ? "charging" : "discharging");
898 lcd_puts(0, 0, "Power status:");
900 battery_read_info(&y
, NULL
);
901 lcd_putsf(0, 1, "Battery: %d.%03d V", y
/ 1000, y
% 1000);
903 y
= (adc_read(ADC_EXT_POWER
) * EXT_SCALE_FACTOR
) / 1000;
904 lcd_putsf(0, 2, "External: %d.%03d V", y
/ 1000, y
% 1000);
907 #if defined ARCHOS_RECORDER
908 lcd_putsf(0, 3, "Chgr: %s %s",
909 charger_inserted() ? "present" : "absent",
910 charger_enabled() ? "on" : "off");
911 lcd_putsf(0, 5, "short delta: %d", short_delta
);
912 lcd_putsf(0, 6, "long delta: %d", long_delta
);
913 lcd_puts(0, 7, power_message
);
914 lcd_putsf(0, 8, "USB Inserted: %s",
915 usb_inserted() ? "yes" : "no");
916 #elif defined IPOD_NANO || defined IPOD_VIDEO
917 int usb_pwr
= (GPIOL_INPUT_VAL
& 0x10)?true:false;
918 int ext_pwr
= (GPIOL_INPUT_VAL
& 0x08)?false:true;
919 int dock
= (GPIOA_INPUT_VAL
& 0x10)?true:false;
920 int charging
= (GPIOB_INPUT_VAL
& 0x01)?false:true;
921 int headphone
= (GPIOA_INPUT_VAL
& 0x80)?true:false;
923 lcd_putsf(0, 3, "USB pwr: %s",
924 usb_pwr
? "present" : "absent");
925 lcd_putsf(0, 4, "EXT pwr: %s",
926 ext_pwr
? "present" : "absent");
927 lcd_putsf(0, 5, "Battery: %s",
928 charging
? "charging" : (usb_pwr
||ext_pwr
) ? "charged" : "discharging");
929 lcd_putsf(0, 6, "Dock mode: %s",
930 dock
? "enabled" : "disabled");
931 lcd_putsf(0, 7, "Headphone: %s",
932 headphone
? "connected" : "disconnected");
934 if(probed_ramsize
== 64)
935 x
= (adc_read(ADC_4066_ISTAT
) * 2400) / (1024 * 2);
938 x
= (adc_read(ADC_4066_ISTAT
) * 2400) / (1024 * 3);
939 lcd_putsf(0, 8, "Ibat: %d mA", x
);
940 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x
* y
/ 1000);
941 #elif defined TOSHIBA_GIGABEAT_S
945 static const unsigned char * const chrgstate_strings
[] =
956 lcd_putsf(0, line
++, "Charger: %s",
957 charger_inserted() ? "present" : "absent");
959 st
= power_input_status() &
960 (POWER_INPUT_CHARGER
| POWER_INPUT_BATTERY
);
961 lcd_putsf(0, line
++, "%s%s",
962 (st
& POWER_INPUT_MAIN_CHARGER
) ? " Main" : "",
963 (st
& POWER_INPUT_USB_CHARGER
) ? " USB" : "");
965 y
= ARRAYLEN(chrgstate_strings
) - 1;
967 switch (charge_state
)
969 case CHARGE_STATE_DISABLED
: y
--;
970 case CHARGE_STATE_ERROR
: y
--;
971 case DISCHARGING
: y
--;
978 lcd_putsf(0, line
++, "State: %s", chrgstate_strings
[y
]);
980 lcd_putsf(0, line
++, "Battery Switch: %s",
981 (st
& POWER_INPUT_BATTERY
) ? "On" : "Off");
983 y
= chrgraw_adc_voltage();
984 lcd_putsf(0, line
++, "CHRGRAW: %d.%03d V",
987 y
= application_supply_adc_voltage();
988 lcd_putsf(0, line
++, "BP : %d.%03d V",
991 y
= battery_adc_charge_current();
992 if (y
< 0) x
= '-', y
= -y
;
994 lcd_putsf(0, line
++, "CHRGISN:%c%d mA", x
, y
);
996 y
= cccv_regulator_dissipation();
997 lcd_putsf(0, line
++, "P CCCV : %d mW", y
);
999 y
= battery_charge_current();
1000 if (y
< 0) x
= '-', y
= -y
;
1002 lcd_putsf(0, line
++, "I Charge:%c%d mA", x
, y
);
1004 y
= battery_adc_temp();
1007 lcd_putsf(0, line
++, "T Battery: %dC (%dF)", y
,
1010 /* Conversion disabled */
1011 lcd_puts(0, line
++, "T Battery: ?");
1014 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1015 CONFIG_CPU == AS3525v2
1016 static const char * const chrgstate_strings
[] =
1018 [CHARGE_STATE_DISABLED
- CHARGE_STATE_DISABLED
]= "Disabled",
1019 [CHARGE_STATE_ERROR
- CHARGE_STATE_DISABLED
] = "Error",
1020 [DISCHARGING
- CHARGE_STATE_DISABLED
] = "Discharging",
1021 [CHARGING
- CHARGE_STATE_DISABLED
] = "Charging",
1023 const char *str
= NULL
;
1025 lcd_putsf(0, 3, "Charger: %s",
1026 charger_inserted() ? "present" : "absent");
1028 y
= charge_state
- CHARGE_STATE_DISABLED
;
1029 if ((unsigned)y
< ARRAYLEN(chrgstate_strings
))
1030 str
= chrgstate_strings
[y
];
1032 lcd_putsf(0, 4, "State: %s",
1033 str
? str
: "<unknown>");
1035 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1036 #elif defined(IPOD_NANO2G)
1037 y
= pmu_read_battery_voltage();
1038 lcd_putsf(17, 1, "RAW: %d.%03d V", y
/ 1000, y
% 1000);
1039 y
= pmu_read_battery_current();
1040 lcd_putsf(0, 2, "Battery current: %d mA", y
);
1041 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON
, PWRCONEXT
);
1042 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON
, CLKCON2
, CLKCON3
);
1043 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS
, PLL1PMS
, PLL2PMS
);
1044 x
= pmu_read(0x1b) & 0xf;
1045 y
= pmu_read(0x1a) * 25 + 625;
1046 lcd_putsf(0, 6, "AUTO: %x / %d mV", x
, y
);
1047 x
= pmu_read(0x1f) & 0xf;
1048 y
= pmu_read(0x1e) * 25 + 625;
1049 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x
, y
);
1050 x
= pmu_read(0x23) & 0xf;
1051 y
= pmu_read(0x22) * 25 + 625;
1052 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x
, y
);
1053 x
= pmu_read(0x27) & 0xf;
1054 y
= pmu_read(0x26) * 100 + 900;
1055 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x
, y
);
1056 for (i
= 0; i
< 6; i
++)
1058 x
= pmu_read(0x2e + (i
<< 1)) & 0xf;
1059 y
= pmu_read(0x2d + (i
<< 1)) * 100 + 900;
1060 lcd_putsf(0, 10 + i
, "LDO%d: %x / %d mV", i
+ 1, x
, y
);
1063 lcd_putsf(0, 3, "Charger: %s",
1064 charger_inserted() ? "present" : "absent");
1065 #endif /* target type */
1066 #endif /* CONFIG_CHARGING */
1069 case 2: /* voltage deltas: */
1070 lcd_puts(0, 0, "Voltage deltas:");
1072 for (i
= 0; i
<= 6; i
++) {
1073 y
= power_history
[i
] - power_history
[i
+1];
1074 lcd_putsf(0, i
+1, "-%d min: %s%d.%03d V", i
,
1075 (y
< 0) ? "-" : "", ((y
< 0) ? y
* -1 : y
) / 1000,
1076 ((y
< 0) ? y
* -1 : y
) % 1000);
1080 case 3: /* remaining time estimation: */
1082 #ifdef ARCHOS_RECORDER
1083 lcd_putsf(0, 0, "charge_state: %d", charge_state
);
1085 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min
);
1087 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level
);
1089 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p
, pid_i
);
1091 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec
);
1092 #endif /* ARCHOS_RECORDER */
1094 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1095 power_history
[0] / 1000,
1096 power_history
[0] % 1000);
1098 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1100 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1106 switch(get_action(CONTEXT_STD
,HZ
/2))
1108 case ACTION_STD_PREV
:
1113 case ACTION_STD_NEXT
:
1118 case ACTION_STD_CANCEL
:
1119 lcd_setfont(FONT_UI
);
1123 lcd_setfont(FONT_UI
);
1127 #endif /* HAVE_LCD_BITMAP */
1130 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1131 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1133 #if (CONFIG_STORAGE & STORAGE_MMC)
1134 #define CARDTYPE "MMC"
1135 #elif (CONFIG_STORAGE & STORAGE_SD)
1136 #define CARDTYPE "microSD"
1139 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1142 int *cardnum
= (int*)lists
->data
;
1143 unsigned char card_name
[6];
1144 unsigned char pbuf
[32];
1145 char *title
= lists
->title
;
1146 static const unsigned char i_vmin
[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1147 static const unsigned char i_vmax
[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1148 static const unsigned char * const kbit_units
[] = { "kBit/s", "MBit/s", "GBit/s" };
1149 static const unsigned char * const nsec_units
[] = { "ns", "µs", "ms" };
1150 #if (CONFIG_STORAGE & STORAGE_MMC)
1151 static const char * const mmc_spec_vers
[] = { "1.0-1.2", "1.4", "2.0-2.2",
1152 "3.1-3.31", "4.0" };
1155 if ((btn
== ACTION_STD_OK
) || (btn
== SYS_FS_CHANGED
) || (btn
== ACTION_REDRAW
))
1158 if (btn
== ACTION_STD_OK
)
1160 *cardnum
^= 0x1; /* change cards */
1164 simplelist_set_line_count(0);
1166 card
= card_get_info(*cardnum
);
1168 if (card
->initialized
> 0)
1171 for (i
=0; i
<sizeof(card_name
); i
++)
1173 card_name
[i
] = card_extract_bits(card
->cid
, (103-8*i
), 8);
1175 strlcpy(card_name
, card_name
, sizeof(card_name
));
1176 simplelist_addline(SIMPLELIST_ADD_LINE
,
1177 "%s Rev %d.%d", card_name
,
1178 (int) card_extract_bits(card
->cid
, 63, 4),
1179 (int) card_extract_bits(card
->cid
, 59, 4));
1180 simplelist_addline(SIMPLELIST_ADD_LINE
,
1182 #if (CONFIG_STORAGE & STORAGE_SD)
1183 (int) card_extract_bits(card
->cid
, 11, 4),
1184 (int) card_extract_bits(card
->cid
, 19, 8) + 2000
1185 #elif (CONFIG_STORAGE & STORAGE_MMC)
1186 (int) card_extract_bits(card
->cid
, 15, 4),
1187 (int) card_extract_bits(card
->cid
, 11, 4) + 1997
1190 simplelist_addline(SIMPLELIST_ADD_LINE
,
1191 #if (CONFIG_STORAGE & STORAGE_SD)
1193 card_extract_bits(card
->cid
, 55, 32)
1194 #elif (CONFIG_STORAGE & STORAGE_MMC)
1196 card_extract_bits(card
->cid
, 47, 16)
1200 simplelist_addline(SIMPLELIST_ADD_LINE
, "M=%02x, "
1201 #if (CONFIG_STORAGE & STORAGE_SD)
1203 (int) card_extract_bits(card
->cid
, 127, 8),
1204 card_extract_bits(card
->cid
, 119, 8),
1205 card_extract_bits(card
->cid
, 111, 8)
1206 #elif (CONFIG_STORAGE & STORAGE_MMC)
1208 (int) card_extract_bits(card
->cid
, 127, 8),
1209 (int) card_extract_bits(card
->cid
, 119, 16)
1213 #if (CONFIG_STORAGE & STORAGE_MMC)
1214 int temp
= card_extract_bits(card
->csd
, 125, 4);
1215 simplelist_addline(SIMPLELIST_ADD_LINE
,
1216 "MMC v%s", temp
< 5 ?
1217 mmc_spec_vers
[temp
] : "?.?");
1219 simplelist_addline(SIMPLELIST_ADD_LINE
,
1220 "Blocks: 0x%08lx", card
->numblocks
);
1221 output_dyn_value(pbuf
, sizeof pbuf
, card
->speed
/ 1000,
1223 simplelist_addline(SIMPLELIST_ADD_LINE
,
1225 output_dyn_value(pbuf
, sizeof pbuf
, card
->taac
,
1227 simplelist_addline(SIMPLELIST_ADD_LINE
,
1229 simplelist_addline(SIMPLELIST_ADD_LINE
,
1230 "Nsac: %d clk", card
->nsac
);
1231 simplelist_addline(SIMPLELIST_ADD_LINE
,
1232 "R2W: *%d", card
->r2w_factor
);
1233 #if (CONFIG_STORAGE & STORAGE_SD)
1234 int csd_structure
= card_extract_bits(card
->csd
, 127, 2);
1235 if (csd_structure
== 0) /* CSD version 1.0 */
1238 simplelist_addline(SIMPLELIST_ADD_LINE
,
1240 i_vmin
[card_extract_bits(card
->csd
, 61, 3)],
1241 i_vmax
[card_extract_bits(card
->csd
, 58, 3)]);
1242 simplelist_addline(SIMPLELIST_ADD_LINE
,
1244 i_vmin
[card_extract_bits(card
->csd
, 55, 3)],
1245 i_vmax
[card_extract_bits(card
->csd
, 52, 3)]);
1248 else if (card
->initialized
== 0)
1250 simplelist_addline(SIMPLELIST_ADD_LINE
, "Not Found!");
1252 #if (CONFIG_STORAGE & STORAGE_SD)
1253 else /* card->initialized < 0 */
1255 simplelist_addline(SIMPLELIST_ADD_LINE
, "Init Error! (%d)", card
->initialized
);
1258 snprintf(title
, 16, "[" CARDTYPE
" %d]", *cardnum
);
1259 gui_synclist_set_title(lists
, title
, Icon_NOICON
);
1260 gui_synclist_set_nb_items(lists
, simplelist_get_line_count());
1261 gui_synclist_select_item(lists
, 0);
1262 btn
= ACTION_REDRAW
;
1266 #elif (CONFIG_STORAGE & STORAGE_ATA)
1267 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1272 unsigned short* identify_info
= ata_get_identify();
1273 bool timing_info_present
= false;
1276 simplelist_set_line_count(0);
1278 for (i
=0; i
< 20; i
++)
1279 ((unsigned short*)buf
)[i
]=htobe16(identify_info
[i
+27]);
1281 /* kill trailing space */
1282 for (i
=39; i
&& buf
[i
]==' '; i
--)
1284 simplelist_addline(SIMPLELIST_ADD_LINE
, "Model: %s", buf
);
1285 for (i
=0; i
< 4; i
++)
1286 ((unsigned short*)buf
)[i
]=htobe16(identify_info
[i
+23]);
1288 simplelist_addline(SIMPLELIST_ADD_LINE
,
1289 "Firmware: %s", buf
);
1290 snprintf(buf
, sizeof buf
, "%ld MB",
1291 ((unsigned long)identify_info
[61] << 16 |
1292 (unsigned long)identify_info
[60]) / 2048 );
1293 simplelist_addline(SIMPLELIST_ADD_LINE
,
1296 fat_size( IF_MV2(0,) NULL
, &free
);
1297 simplelist_addline(SIMPLELIST_ADD_LINE
,
1298 "Free: %ld MB", free
/ 1024);
1299 simplelist_addline(SIMPLELIST_ADD_LINE
,
1300 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ
));
1301 i
= identify_info
[83] & (1<<3);
1302 simplelist_addline(SIMPLELIST_ADD_LINE
,
1303 "Power mgmt: %s", i
? "enabled" : "unsupported");
1304 i
= identify_info
[83] & (1<<9);
1305 simplelist_addline(SIMPLELIST_ADD_LINE
,
1306 "Noise mgmt: %s", i
? "enabled" : "unsupported");
1307 i
= identify_info
[82] & (1<<6);
1308 simplelist_addline(SIMPLELIST_ADD_LINE
,
1309 "Read-ahead: %s", i
? "enabled" : "unsupported");
1310 timing_info_present
= identify_info
[53] & (1<<1);
1311 if(timing_info_present
) {
1312 char pio3
[2], pio4
[2];pio3
[1] = 0;
1314 pio3
[0] = (identify_info
[64] & (1<<0)) ? '3' : 0;
1315 pio4
[0] = (identify_info
[64] & (1<<1)) ? '4' : 0;
1316 simplelist_addline(SIMPLELIST_ADD_LINE
,
1317 "PIO modes: 0 1 2 %s %s", pio3
, pio4
);
1320 simplelist_addline(SIMPLELIST_ADD_LINE
,
1321 "No PIO mode info");
1323 timing_info_present
= identify_info
[53] & (1<<1);
1324 if(timing_info_present
) {
1325 simplelist_addline(SIMPLELIST_ADD_LINE
,
1326 "Cycle times %dns/%dns",
1328 identify_info
[68] );
1330 simplelist_addline(SIMPLELIST_ADD_LINE
,
1333 int sector_size
= 512;
1334 if((identify_info
[106] & 0xe000) == 0x6000)
1335 sector_size
*= BIT_N(identify_info
[106] & 0x000f);
1336 simplelist_addline(SIMPLELIST_ADD_LINE
,
1337 "Physical sector size: %d", sector_size
);
1339 if (identify_info
[63] & (1<<0)) {
1340 char mdma0
[2], mdma1
[2], mdma2
[2];
1341 mdma0
[1] = mdma1
[1] = mdma2
[1] = 0;
1342 mdma0
[0] = (identify_info
[63] & (1<<0)) ? '0' : 0;
1343 mdma1
[0] = (identify_info
[63] & (1<<1)) ? '1' : 0;
1344 mdma2
[0] = (identify_info
[63] & (1<<2)) ? '2' : 0;
1345 simplelist_addline(SIMPLELIST_ADD_LINE
,
1346 "MDMA modes: %s %s %s", mdma0
, mdma1
, mdma2
);
1347 simplelist_addline(SIMPLELIST_ADD_LINE
,
1348 "MDMA Cycle times %dns/%dns",
1350 identify_info
[66] );
1353 simplelist_addline(SIMPLELIST_ADD_LINE
,
1354 "No MDMA mode info");
1356 if (identify_info
[53] & (1<<2)) {
1357 char udma0
[2], udma1
[2], udma2
[2], udma3
[2], udma4
[2], udma5
[2], udma6
[2];
1358 udma0
[1] = udma1
[1] = udma2
[1] = udma3
[1] = udma4
[1] = udma5
[1] = udma6
[1] = 0;
1359 udma0
[0] = (identify_info
[88] & (1<<0)) ? '0' : 0;
1360 udma1
[0] = (identify_info
[88] & (1<<1)) ? '1' : 0;
1361 udma2
[0] = (identify_info
[88] & (1<<2)) ? '2' : 0;
1362 udma3
[0] = (identify_info
[88] & (1<<3)) ? '3' : 0;
1363 udma4
[0] = (identify_info
[88] & (1<<4)) ? '4' : 0;
1364 udma5
[0] = (identify_info
[88] & (1<<5)) ? '5' : 0;
1365 udma6
[0] = (identify_info
[88] & (1<<6)) ? '6' : 0;
1366 simplelist_addline(SIMPLELIST_ADD_LINE
,
1367 "UDMA modes: %s %s %s %s %s %s %s", udma0
, udma1
, udma2
,
1368 udma3
, udma4
, udma5
, udma6
);
1371 simplelist_addline(SIMPLELIST_ADD_LINE
,
1372 "No UDMA mode info");
1374 #endif /* HAVE_ATA_DMA */
1375 timing_info_present
= identify_info
[53] & (1<<1);
1376 if(timing_info_present
) {
1377 i
= identify_info
[49] & (1<<11);
1378 simplelist_addline(SIMPLELIST_ADD_LINE
,
1379 "IORDY support: %s", i
? "yes" : "no");
1380 i
= identify_info
[49] & (1<<10);
1381 simplelist_addline(SIMPLELIST_ADD_LINE
,
1382 "IORDY disable: %s", i
? "yes" : "no");
1384 simplelist_addline(SIMPLELIST_ADD_LINE
,
1387 simplelist_addline(SIMPLELIST_ADD_LINE
,
1388 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1390 i
= ata_get_dma_mode();
1392 simplelist_addline(SIMPLELIST_ADD_LINE
,
1395 simplelist_addline(SIMPLELIST_ADD_LINE
,
1397 (i
& 0x40) ? "UDMA" : "MDMA",
1400 #endif /* HAVE_ATA_DMA */
1403 #else /* No SD, MMC or ATA */
1404 static int disk_callback(int btn
, struct gui_synclist
*lists
)
1408 struct storage_info info
;
1409 storage_get_info(0,&info
);
1410 simplelist_addline(SIMPLELIST_ADD_LINE
, "Vendor: %s", info
.vendor
);
1411 simplelist_addline(SIMPLELIST_ADD_LINE
, "Model: %s", info
.product
);
1412 simplelist_addline(SIMPLELIST_ADD_LINE
, "Firmware: %s", info
.revision
);
1413 simplelist_addline(SIMPLELIST_ADD_LINE
,
1414 "Size: %ld MB", info
.num_sectors
*(info
.sector_size
/512)/2024);
1416 fat_size( IF_MV2(0,) NULL
, &free
);
1417 simplelist_addline(SIMPLELIST_ADD_LINE
,
1418 "Free: %ld MB", free
/ 1024);
1419 simplelist_addline(SIMPLELIST_ADD_LINE
,
1420 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1425 #if (CONFIG_STORAGE & STORAGE_ATA)
1426 static bool dbg_identify_info(void)
1428 int fd
= creat("/identify_info.bin", 0666);
1431 #ifdef ROCKBOX_LITTLE_ENDIAN
1432 ecwrite(fd
, ata_get_identify(), SECTOR_SIZE
/2, "s", true);
1434 write(fd
, ata_get_identify(), SECTOR_SIZE
);
1442 static bool dbg_disk_info(void)
1444 struct simplelist_info info
;
1445 simplelist_info_init(&info
, "Disk Info", 1, NULL
);
1446 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1449 info
.callback_data
= (void*)&card
;
1452 info
.action_callback
= disk_callback
;
1453 info
.hide_selection
= true;
1454 info
.scroll_all
= true;
1455 return simplelist_show_list(&info
);
1457 #endif /* PLATFORM_NATIVE */
1459 #ifdef HAVE_DIRCACHE
1460 static int dircache_callback(int btn
, struct gui_synclist
*lists
)
1462 (void)btn
; (void)lists
;
1463 simplelist_set_line_count(0);
1464 simplelist_addline(SIMPLELIST_ADD_LINE
, "Cache initialized: %s",
1465 dircache_is_enabled() ? "Yes" : "No");
1466 simplelist_addline(SIMPLELIST_ADD_LINE
, "Cache size: %d B",
1467 dircache_get_cache_size());
1468 simplelist_addline(SIMPLELIST_ADD_LINE
, "Last size: %d B",
1469 global_status
.dircache_size
);
1470 simplelist_addline(SIMPLELIST_ADD_LINE
, "Limit: %d B",
1472 simplelist_addline(SIMPLELIST_ADD_LINE
, "Reserve: %d/%d B",
1473 dircache_get_reserve_used(), DIRCACHE_RESERVE
);
1474 simplelist_addline(SIMPLELIST_ADD_LINE
, "Scanning took: %d s",
1475 dircache_get_build_ticks() / HZ
);
1476 simplelist_addline(SIMPLELIST_ADD_LINE
, "Entry count: %d",
1477 dircache_get_entry_count());
1481 static bool dbg_dircache_info(void)
1483 struct simplelist_info info
;
1484 simplelist_info_init(&info
, "Dircache Info", 7, NULL
);
1485 info
.action_callback
= dircache_callback
;
1486 info
.hide_selection
= true;
1487 info
.scroll_all
= true;
1488 return simplelist_show_list(&info
);
1491 #endif /* HAVE_DIRCACHE */
1493 #ifdef HAVE_TAGCACHE
1494 static int database_callback(int btn
, struct gui_synclist
*lists
)
1497 struct tagcache_stat
*stat
= tagcache_get_stat();
1498 static bool synced
= false;
1500 simplelist_set_line_count(0);
1502 simplelist_addline(SIMPLELIST_ADD_LINE
, "Initialized: %s",
1503 stat
->initialized
? "Yes" : "No");
1504 simplelist_addline(SIMPLELIST_ADD_LINE
, "DB Ready: %s",
1505 stat
->ready
? "Yes" : "No");
1506 simplelist_addline(SIMPLELIST_ADD_LINE
, "RAM Cache: %s",
1507 stat
->ramcache
? "Yes" : "No");
1508 simplelist_addline(SIMPLELIST_ADD_LINE
, "RAM: %d/%d B",
1509 stat
->ramcache_used
, stat
->ramcache_allocated
);
1510 simplelist_addline(SIMPLELIST_ADD_LINE
, "Progress: %d%% (%d entries)",
1511 stat
->progress
, stat
->processed_entries
);
1512 simplelist_addline(SIMPLELIST_ADD_LINE
, "Curfile: %s",
1513 stat
->curentry
? stat
->curentry
: "---");
1514 simplelist_addline(SIMPLELIST_ADD_LINE
, "Commit step: %d",
1516 simplelist_addline(SIMPLELIST_ADD_LINE
, "Commit delayed: %s",
1517 stat
->commit_delayed
? "Yes" : "No");
1519 simplelist_addline(SIMPLELIST_ADD_LINE
, "Queue length: %d",
1520 stat
->queue_length
);
1525 tagcache_screensync_event();
1528 if (!btn
&& stat
->curentry
)
1531 return ACTION_REDRAW
;
1534 if (btn
== ACTION_STD_CANCEL
)
1535 tagcache_screensync_enable(false);
1539 static bool dbg_tagcache_info(void)
1541 struct simplelist_info info
;
1542 simplelist_info_init(&info
, "Database Info", 8, NULL
);
1543 info
.action_callback
= database_callback
;
1544 info
.hide_selection
= true;
1545 info
.scroll_all
= true;
1547 /* Don't do nonblock here, must give enough processing time
1548 for tagcache thread. */
1549 /* info.timeout = TIMEOUT_NOBLOCK; */
1551 tagcache_screensync_enable(true);
1552 return simplelist_show_list(&info
);
1556 #if CONFIG_CPU == SH7034
1557 static bool dbg_save_roms(void)
1560 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
1562 fd
= creat("/internal_rom_0000-FFFF.bin", 0666);
1565 write(fd
, (void *)0, 0x10000);
1569 fd
= creat("/internal_rom_2000000-203FFFF.bin", 0666);
1572 write(fd
, (void *)0x2000000, 0x40000);
1576 system_memory_guard(oldmode
);
1579 #elif defined CPU_COLDFIRE
1580 static bool dbg_save_roms(void)
1583 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
1585 #if defined(IRIVER_H100_SERIES)
1586 fd
= creat("/internal_rom_000000-1FFFFF.bin", 0666);
1587 #elif defined(IRIVER_H300_SERIES)
1588 fd
= creat("/internal_rom_000000-3FFFFF.bin", 0666);
1589 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1590 fd
= creat("/internal_rom_000000-3FFFFF.bin", 0666);
1591 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1592 fd
= creat("/internal_rom_000000-1FFFFF.bin", 0666);
1596 write(fd
, (void *)0, FLASH_SIZE
);
1599 system_memory_guard(oldmode
);
1602 fd
= creat("/internal_eeprom.bin", 0666);
1606 char buf
[EEPROM_SIZE
];
1609 old_irq_level
= disable_irq_save();
1611 err
= eeprom_24cxx_read(0, buf
, sizeof buf
);
1613 restore_irq(old_irq_level
);
1616 splashf(HZ
*3, "Eeprom read failure (%d)", err
);
1619 write(fd
, buf
, sizeof buf
);
1628 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1629 static bool dbg_save_roms(void)
1633 fd
= creat("/internal_rom_000000-0FFFFF.bin", 0666);
1636 write(fd
, (void *)0x20000000, FLASH_SIZE
);
1642 #elif CONFIG_CPU == IMX31L
1643 static bool dbg_save_roms(void)
1647 fd
= creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1650 write(fd
, (void*)0xa0000000, FLASH_SIZE
);
1656 #elif defined(CPU_TCC780X)
1657 static bool dbg_save_roms(void)
1661 fd
= creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1664 write(fd
, (void*)0xe0000000, 0x2000);
1675 #ifdef CONFIG_TUNER_MULTI
1676 static int tuner_type
= 0;
1677 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1679 #define IF_TUNER_TYPE(type)
1682 static int radio_callback(int btn
, struct gui_synclist
*lists
)
1685 if (btn
== ACTION_STD_CANCEL
)
1687 simplelist_set_line_count(1);
1689 #if (CONFIG_TUNER & LV24020LP)
1690 simplelist_addline(SIMPLELIST_ADD_LINE
,
1691 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT
) );
1692 simplelist_addline(SIMPLELIST_ADD_LINE
,
1693 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT
) );
1694 simplelist_addline(SIMPLELIST_ADD_LINE
,
1695 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM
) );
1696 simplelist_addline(SIMPLELIST_ADD_LINE
,
1697 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF
) );
1698 simplelist_addline(SIMPLELIST_ADD_LINE
,
1699 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD
) );
1700 simplelist_addline(SIMPLELIST_ADD_LINE
,
1701 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET
) );
1702 simplelist_addline(SIMPLELIST_ADD_LINE
,
1703 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET
) );
1704 #endif /* LV24020LP */
1705 #if (CONFIG_TUNER & S1A0903X01)
1706 simplelist_addline(SIMPLELIST_ADD_LINE
,
1707 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL
));
1708 /* This one doesn't return dynamic data atm */
1709 #endif /* S1A0903X01 */
1710 #if (CONFIG_TUNER & TEA5767)
1711 struct tea5767_dbg_info nfo
;
1712 tea5767_dbg_info(&nfo
);
1713 simplelist_addline(SIMPLELIST_ADD_LINE
, "Philips regs:");
1714 simplelist_addline(SIMPLELIST_ADD_LINE
,
1715 " Read: %02X %02X %02X %02X %02X",
1716 (unsigned)nfo
.read_regs
[0], (unsigned)nfo
.read_regs
[1],
1717 (unsigned)nfo
.read_regs
[2], (unsigned)nfo
.read_regs
[3],
1718 (unsigned)nfo
.read_regs
[4]);
1719 simplelist_addline(SIMPLELIST_ADD_LINE
,
1720 " Write: %02X %02X %02X %02X %02X",
1721 (unsigned)nfo
.write_regs
[0], (unsigned)nfo
.write_regs
[1],
1722 (unsigned)nfo
.write_regs
[2], (unsigned)nfo
.write_regs
[3],
1723 (unsigned)nfo
.write_regs
[4]);
1724 #endif /* TEA5767 */
1725 #if (CONFIG_TUNER & SI4700)
1726 IF_TUNER_TYPE(SI4700
)
1728 struct si4700_dbg_info nfo
;
1730 si4700_dbg_info(&nfo
);
1731 simplelist_addline(SIMPLELIST_ADD_LINE
, "SI4700 regs:");
1732 for (i
= 0; i
< 16; i
+= 4) {
1733 simplelist_addline(SIMPLELIST_ADD_LINE
,"%02X: %04X %04X %04X %04X",
1734 i
, nfo
.regs
[i
], nfo
.regs
[i
+1], nfo
.regs
[i
+2], nfo
.regs
[i
+3]);
1738 #if (CONFIG_TUNER & RDA5802)
1739 IF_TUNER_TYPE(RDA5802
)
1741 struct rda5802_dbg_info nfo
;
1743 rda5802_dbg_info(&nfo
);
1744 simplelist_addline(SIMPLELIST_ADD_LINE
, "RDA5802 regs:");
1745 for (i
= 0; i
< 16; i
+= 4) {
1746 simplelist_addline(SIMPLELIST_ADD_LINE
,"%02X: %04X %04X %04X %04X",
1747 i
, nfo
.regs
[i
], nfo
.regs
[i
+1], nfo
.regs
[i
+2], nfo
.regs
[i
+3]);
1750 #endif /* RDA55802 */
1751 return ACTION_REDRAW
;
1753 static bool dbg_fm_radio(void)
1755 struct simplelist_info info
;
1756 #ifdef CONFIG_TUNER_MULTI
1757 tuner_type
= tuner_detect_type();
1759 info
.scroll_all
= true;
1760 simplelist_info_init(&info
, "FM Radio", 1, NULL
);
1761 simplelist_set_line_count(0);
1762 simplelist_addline(SIMPLELIST_ADD_LINE
, "HW detected: %s",
1763 radio_hardware_present() ? "yes" : "no");
1765 info
.action_callback
= radio_hardware_present()?radio_callback
: NULL
;
1766 info
.hide_selection
= true;
1767 return simplelist_show_list(&info
);
1769 #endif /* CONFIG_TUNER */
1770 #endif /* !SIMULATOR */
1772 #ifdef HAVE_LCD_BITMAP
1773 extern bool do_screendump_instead_of_usb
;
1775 static bool dbg_screendump(void)
1777 do_screendump_instead_of_usb
= !do_screendump_instead_of_usb
;
1778 splashf(HZ
, "Screendump %s",
1779 do_screendump_instead_of_usb
?"enabled":"disabled");
1782 #endif /* HAVE_LCD_BITMAP */
1784 extern bool write_metadata_log
;
1786 static bool dbg_metadatalog(void)
1788 write_metadata_log
= !write_metadata_log
;
1789 splashf(HZ
, "Metadata log %s",
1790 write_metadata_log
?"enabled":"disabled");
1794 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1795 static bool dbg_set_memory_guard(void)
1797 static const struct opt_items names
[MAXMEMGUARD
] = {
1799 { "Flash ROM writes", -1 },
1800 { "Zero area (all)", -1 }
1802 int mode
= system_memory_guard(MEMGUARD_KEEP
);
1804 set_option( "Catch mem accesses", &mode
, INT
, names
, MAXMEMGUARD
, NULL
);
1805 system_memory_guard(mode
);
1809 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1811 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
1812 static bool dbg_write_eeprom(void)
1817 char buf
[EEPROM_SIZE
];
1820 fd
= open("/internal_eeprom.bin", O_RDONLY
);
1824 rc
= read(fd
, buf
, EEPROM_SIZE
);
1826 if(rc
== EEPROM_SIZE
)
1828 old_irq_level
= disable_irq_save();
1830 err
= eeprom_24cxx_write(0, buf
, sizeof buf
);
1832 splashf(HZ
*3, "Eeprom write failure (%d)", err
);
1834 splash(HZ
*3, "Eeprom written successfully");
1836 restore_irq(old_irq_level
);
1840 splashf(HZ
*3, "File read error (%d)",rc
);
1846 splash(HZ
*3, "Failed to open 'internal_eeprom.bin'");
1851 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
1852 #ifdef CPU_BOOST_LOGGING
1853 static bool cpu_boost_log(void)
1856 int count
= cpu_boost_log_getcount();
1857 int lines
= LCD_HEIGHT
/SYSFONT_HEIGHT
;
1860 lcd_setfont(FONT_SYSFIXED
);
1861 str
= cpu_boost_log_getlog_first();
1864 lcd_clear_display();
1865 for(j
=0; j
<lines
; j
++,i
++)
1868 str
= cpu_boost_log_getlog_next();
1871 if(strlen(str
) > LCD_WIDTH
/SYSFONT_WIDTH
)
1872 lcd_puts_scroll(0, j
, str
);
1882 switch(get_action(CONTEXT_STD
,TIMEOUT_BLOCK
))
1885 case ACTION_STD_PREV
:
1886 case ACTION_STD_NEXT
:
1889 case ACTION_STD_CANCEL
:
1897 get_action(CONTEXT_STD
,TIMEOUT_BLOCK
);
1898 lcd_setfont(FONT_UI
);
1903 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
1904 && !defined(IPOD_MINI) && !defined(SIMULATOR))
1905 extern bool wheel_is_touched
;
1906 extern int old_wheel_value
;
1907 extern int new_wheel_value
;
1908 extern int wheel_delta
;
1909 extern unsigned int accumulated_wheel_delta
;
1910 extern unsigned int wheel_velocity
;
1912 static bool dbg_scrollwheel(void)
1916 lcd_setfont(FONT_SYSFIXED
);
1920 if (action_userabort(HZ
/10))
1923 lcd_clear_display();
1925 /* show internal variables of scrollwheel driver */
1926 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched
) ? "true" : "false");
1927 lcd_putsf(0, 1, "new position: %2d", new_wheel_value
);
1928 lcd_putsf(0, 2, "old position: %2d", old_wheel_value
);
1929 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta
);
1930 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta
);
1931 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity
);
1933 /* show effective accelerated scrollspeed */
1934 speed
= button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity
);
1935 lcd_putsf(0, 6, "accel. speed: %4d", speed
);
1939 lcd_setfont(FONT_UI
);
1944 #if defined (HAVE_USBSTACK)
1946 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
1947 static bool toggle_usb_core_driver(int driver
, char *msg
)
1949 bool enabled
= !usb_core_driver_enabled(driver
);
1951 usb_core_enable_driver(driver
,enabled
);
1952 splashf(HZ
, "%s %s", msg
, enabled
?"enabled":"disabled");
1957 static bool toggle_usb_serial(void)
1959 return toggle_usb_core_driver(USB_DRIVER_SERIAL
,"USB Serial");
1965 #if CONFIG_USBOTG == USBOTG_ISP1583
1966 extern int dbg_usb_num_items(void);
1967 extern const char* dbg_usb_item(int selected_item
, void *data
,
1968 char *buffer
, size_t buffer_len
);
1970 static int isp1583_action_callback(int action
, struct gui_synclist
*lists
)
1973 if (action
== ACTION_NONE
)
1974 action
= ACTION_REDRAW
;
1978 static bool dbg_isp1583(void)
1980 struct simplelist_info isp1583
;
1981 isp1583
.scroll_all
= true;
1982 simplelist_info_init(&isp1583
, "ISP1583", dbg_usb_num_items(), NULL
);
1983 isp1583
.timeout
= HZ
/100;
1984 isp1583
.hide_selection
= true;
1985 isp1583
.get_name
= dbg_usb_item
;
1986 isp1583
.action_callback
= isp1583_action_callback
;
1987 return simplelist_show_list(&isp1583
);
1991 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
1992 extern int pic_dbg_num_items(void);
1993 extern const char* pic_dbg_item(int selected_item
, void *data
,
1994 char *buffer
, size_t buffer_len
);
1996 static int pic_action_callback(int action
, struct gui_synclist
*lists
)
1999 if (action
== ACTION_NONE
)
2000 action
= ACTION_REDRAW
;
2004 static bool dbg_pic(void)
2006 struct simplelist_info pic
;
2007 pic
.scroll_all
= true;
2008 simplelist_info_init(&pic
, "PIC", pic_dbg_num_items(), NULL
);
2009 pic
.timeout
= HZ
/100;
2010 pic
.hide_selection
= true;
2011 pic
.get_name
= pic_dbg_item
;
2012 pic
.action_callback
= pic_action_callback
;
2013 return simplelist_show_list(&pic
);
2018 /****** The menu *********/
2019 struct the_menu_item
{
2020 unsigned char *desc
; /* string or ID */
2021 bool (*function
) (void); /* return true if USB was connected */
2023 static const struct the_menu_item menuitems
[] = {
2024 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2025 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2026 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2027 { "Dump ROM contents", dbg_save_roms
},
2029 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2030 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2031 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2 \
2032 || CONFIG_CPU == RK27XX
2033 { "View I/O ports", dbg_ports
},
2035 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2036 { "View PCF registers", dbg_pcf
},
2038 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2039 { "TSC2100 debug", tsc2100_debug
},
2041 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2042 { "CPU frequency", dbg_cpufreq
},
2044 #if CONFIG_CPU == IMX31L
2045 { "DVFS/DPTC", __dbg_dvfs_dptc
},
2047 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2048 { "S/PDIF analyzer", dbg_spdif
},
2050 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2051 { "Catch mem accesses", dbg_set_memory_guard
},
2053 { "View OS stacks", dbg_os
},
2054 #ifdef HAVE_LCD_BITMAP
2055 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2056 { "View battery", view_battery
},
2058 { "Screendump", dbg_screendump
},
2060 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2061 { "View HW info", dbg_hw_info
},
2063 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2064 { "View partitions", dbg_partitions
},
2066 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2067 { "View disk info", dbg_disk_info
},
2068 #if (CONFIG_STORAGE & STORAGE_ATA)
2069 { "Dump ATA identify info", dbg_identify_info
},
2072 { "Metadata log", dbg_metadatalog
},
2073 #ifdef HAVE_DIRCACHE
2074 { "View dircache info", dbg_dircache_info
},
2076 #ifdef HAVE_TAGCACHE
2077 { "View database info", dbg_tagcache_info
},
2079 #ifdef HAVE_LCD_BITMAP
2080 #if CONFIG_CODEC == SWCODEC
2081 { "View buffering thread", dbg_buffering_thread
},
2082 #elif !defined(SIMULATOR)
2083 { "View audio thread", dbg_audio_thread
},
2086 { "pm histogram", peak_meter_histogram
},
2087 #endif /* PM_DEBUG */
2088 #endif /* HAVE_LCD_BITMAP */
2089 { "View buflib allocs", dbg_buflib_allocs
},
2092 { "FM Radio", dbg_fm_radio
},
2095 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2096 { "Write back EEPROM", dbg_write_eeprom
},
2098 #if CONFIG_USBOTG == USBOTG_ISP1583
2099 { "View ISP1583 info", dbg_isp1583
},
2101 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2102 { "View PIC info", dbg_pic
},
2104 #ifdef ROCKBOX_HAS_LOGF
2105 {"Show Log File", logfdisplay
},
2106 {"Dump Log File", logfdump
},
2108 #if defined(HAVE_USBSTACK)
2109 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2110 {"USB Serial driver (logf)", toggle_usb_serial
},
2112 #endif /* HAVE_USBSTACK */
2113 #ifdef CPU_BOOST_LOGGING
2114 {"cpu_boost log",cpu_boost_log
},
2116 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2117 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2118 {"Debug scrollwheel", dbg_scrollwheel
},
2121 static int menu_action_callback(int btn
, struct gui_synclist
*lists
)
2123 if (btn
== ACTION_STD_OK
)
2126 viewportmanager_theme_enable(i
, false, NULL
);
2127 menuitems
[gui_synclist_get_sel_pos(lists
)].function();
2128 btn
= ACTION_REDRAW
;
2130 viewportmanager_theme_undo(i
, false);
2135 static const char* dbg_menu_getname(int item
, void * data
,
2136 char *buffer
, size_t buffer_len
)
2138 (void)data
; (void)buffer
; (void)buffer_len
;
2139 return menuitems
[item
].desc
;
2142 bool debug_menu(void)
2144 struct simplelist_info info
;
2146 simplelist_info_init(&info
, "Debug Menu", ARRAYLEN(menuitems
), NULL
);
2147 info
.action_callback
= menu_action_callback
;
2148 info
.get_name
= dbg_menu_getname
;
2149 return simplelist_show_list(&info
);