📄 debug_menu.c
字号:
/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: debug_menu.c,v 1.63 2004/03/01 09:42:47 linusnielsen Exp $ * * Copyright (C) 2002 Heikki Hannikainen * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include "config.h"#ifndef SIMULATOR#include <stdio.h>#include <stdbool.h>#include <string.h>#include "lcd.h"#include "menu.h"#include "debug_menu.h"#include "kernel.h"#include "sprintf.h"#include "button.h"#include "adc.h"#include "mas.h"#include "power.h"#include "rtc.h"#include "debug.h"#include "thread.h"#include "powermgmt.h"#include "system.h"#include "font.h"#include "disk.h"#include "mpeg.h"#include "settings.h"#include "ata.h"#include "fat.h"#include "dir.h"#include "panic.h"#ifdef HAVE_LCD_BITMAP#include "widgets.h"#include "peakmeter.h"#endif#ifdef HAVE_FMRADIO#include "radio.h"#endif/*---------------------------------------------------*//* SPECIAL DEBUG STUFF *//*---------------------------------------------------*/extern int ata_device;extern int ata_io_address;extern int num_threads;extern char *thread_name[];#ifdef HAVE_LCD_BITMAP/* Test code!!! */bool dbg_os(void){ char buf[32]; int button; int i; int usage;#ifdef HAVE_LCD_BITMAP lcd_setmargins(0, 0);#endif lcd_clear_display(); while(1) { lcd_puts(0, 0, "Stack usage:"); for(i = 0; i < num_threads;i++) { usage = thread_stack_usage(i); snprintf(buf, 32, "%s: %d%%", thread_name[i], usage); lcd_puts(0, 1+i, buf); } lcd_update(); button = button_get_w_tmo(HZ/10); switch(button) {#ifdef BUTTON_OFF case BUTTON_OFF:#endif case BUTTON_LEFT: return false; } } return false;}#elsebool dbg_os(void){ char buf[32]; int button; int usage; int currval = 0;#ifdef HAVE_LCD_BITMAP lcd_setmargins(0, 0);#endif lcd_clear_display(); while(1) { lcd_puts(0, 0, "Stack usage"); usage = thread_stack_usage(currval); snprintf(buf, 32, "%d: %d%% ", currval, usage); lcd_puts(0, 1, buf); button = button_get_w_tmo(HZ/10); switch(button) { case BUTTON_STOP: return false; case BUTTON_LEFT: currval--; if(currval < 0) currval = num_threads-1; break; case BUTTON_RIGHT: currval++; if(currval > num_threads-1) currval = 0; break; } } return false;}#endif#ifdef HAVE_LCD_BITMAPbool dbg_mpeg_thread(void){ char buf[32]; int button; int percent; struct mpeg_debug d; lcd_setmargins(0, 0); while(1) { button = button_get_w_tmo(HZ/5); switch(button) { case BUTTON_OFF | BUTTON_REL: return false; } mpeg_get_debugdata(&d); lcd_clear_display(); snprintf(buf, sizeof(buf), "read: %x", d.mp3buf_read); lcd_puts(0, 0, buf); snprintf(buf, sizeof(buf), "write: %x", d.mp3buf_write); lcd_puts(0, 1, buf); snprintf(buf, sizeof(buf), "swap: %x", d.mp3buf_swapwrite); lcd_puts(0, 2, buf); snprintf(buf, sizeof(buf), "playing: %d", d.playing); lcd_puts(0, 3, buf); snprintf(buf, sizeof(buf), "playable: %x", d.playable_space); lcd_puts(0, 4, buf); snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space); lcd_puts(0, 5, buf); percent = d.playable_space * 100 / d.mp3buflen; progressbar(0, 6*8, 112, 4, percent, Grow_Right); percent = d.low_watermark_level * 100 / d.mp3buflen; progressbar(0, 6*8+4, 112, 4, percent, Grow_Right); snprintf(buf, sizeof(buf), "wm: %x - %x", d.low_watermark_level, d.lowest_watermark_level); lcd_puts(0, 7, buf); lcd_update(); } return false;}#endif/* Tool function to calculate a CRC16 across some buffer */unsigned short crc_16(unsigned char* buf, unsigned len){ /* CCITT standard polynomial 0x1021 */ static const unsigned short crc16_lookup[16] = { /* lookup table for 4 bits at a time is affordable */ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF }; unsigned short crc16 = 0xFFFF; /* initialise to 0xFFFF (CCITT specification) */ unsigned t; unsigned char byte; while (len--) { byte = *buf++; /* get one byte of data */ /* upper nibble of our data */ t = crc16 >> 12; /* extract the 4 most significant bits */ t ^= byte >> 4; /* XOR in 4 bits of the data into the extracted bits */ crc16 <<= 4; /* shift the CRC Register left 4 bits */ crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */ /* lower nibble of our data */ t = crc16 >> 12; /* extract the 4 most significant bits */ t ^= byte & 0x0F; /* XOR in 4 bits of the data into the extracted bits */ crc16 <<= 4; /* shift the CRC Register left 4 bits */ crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */ } return crc16;}/* Tool function to read the flash manufacturer and type, if available. Only chips which could be reprogrammed in system will return values. (The mode switch addresses vary between flash manufacturers, hence addr1/2) */bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, unsigned addr1, unsigned addr2){ unsigned not_manu, not_id; /* read values before switching to ID mode */ unsigned manu, id; /* read values when in ID mode */ volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */ not_manu = flash[0]; /* read the normal content */ not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */ flash[addr1] = 0xAA; /* enter command mode */ flash[addr2] = 0x55; flash[addr1] = 0x90; /* ID command */ sleep(HZ/50); /* Atmel wants 20ms pause here */ manu = flash[0]; /* read the IDs */ id = flash[1]; flash[0] = 0xF0; /* reset flash (back to normal read mode) */ sleep(HZ/50); /* Atmel wants 20ms pause here */ /* I assume success if the obtained values are different from the normal flash content. This is not perfectly bulletproof, they could theoretically be the same by chance, causing us to fail. */ if (not_manu != manu || not_id != id) /* a value has changed */ { *p_manufacturer = manu; /* return the results */ *p_device = id; return true; /* success */ } return false; /* fail */}#ifdef HAVE_LCD_BITMAPbool dbg_hw_info(void){ char buf[32]; int button; int usb_polarity; int pr_polarity; int bitmask = *(unsigned short*)0x20000fc; int rom_version = *(unsigned short*)0x20000fe; unsigned manu, id; /* flash IDs */ bool got_id; /* flag if we managed to get the flash IDs */ unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */ bool has_bootrom; /* flag for boot ROM present */ if(PADR & 0x400) usb_polarity = 0; /* Negative */ else usb_polarity = 1; /* Positive */ if(PADR & 0x800) pr_polarity = 0; /* Negative */ else pr_polarity = 1; /* Positive */ /* get flash ROM type */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ if (!got_id) got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ /* check if the boot ROM area is a flash mirror */ has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0); if (has_bootrom) /* if ROM and Flash different */ { /* calculate CRC16 checksum of boot ROM */ rom_crc = crc_16((unsigned char*)0x0000, 64*1024); } lcd_setmargins(0, 0); lcd_setfont(FONT_SYSFIXED); lcd_clear_display(); lcd_puts(0, 0, "[Hardware info]"); snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100); lcd_puts(0, 1, buf); snprintf(buf, 32, "Mask: 0x%04x", bitmask); lcd_puts(0, 2, buf); snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative"); lcd_puts(0, 3, buf); snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address, ata_device ? "slave":"master"); lcd_puts(0, 4, buf); snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative"); lcd_puts(0, 5, buf); if (got_id) snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id); else snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */ lcd_puts(0, 6, buf); if (has_bootrom) { snprintf(buf, 32-3, "ROM CRC: 0x%04x", rom_crc); if (rom_crc == 0x222F) /* known Version 1 */ strcat(buf, " V1"); } else { snprintf(buf, 32, "Boot ROM: none"); } lcd_puts(0, 7, buf); lcd_update(); while(1) { button = button_get(true); if(button == (BUTTON_OFF | BUTTON_REL)) return false; } return false;}#elsebool dbg_hw_info(void){ char buf[32]; int button; int currval = 0; int usb_polarity; int bitmask = *(unsigned short*)0x20000fc; int rom_version = *(unsigned short*)0x20000fe; unsigned manu, id; /* flash IDs */ bool got_id; /* flag if we managed to get the flash IDs */ unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */ bool has_bootrom; /* flag for boot ROM present */ if(PADR & 0x400) usb_polarity = 0; /* Negative */ else usb_polarity = 1; /* Positive */ /* get flash ROM type */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ if (!got_id) got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ /* check if the boot ROM area is a flash mirror */ has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0); if (has_bootrom) /* if ROM and Flash different */ { /* calculate CRC16 checksum of boot ROM */ rom_crc = crc_16((unsigned char*)0x0000, 64*1024); } lcd_clear_display(); lcd_puts(0, 0, "[HW Info]"); while(1) { switch(currval) { case 0: snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100); break; case 1: snprintf(buf, 32, "USB: %s", usb_polarity?"pos":"neg"); break; case 2: snprintf(buf, 32, "ATA: 0x%x%s", ata_io_address, ata_device ? "s":"m"); break; case 3: snprintf(buf, 32, "Mask: %04x", bitmask); break; case 4: if (got_id) snprintf(buf, 32, "Flash:%02x,%02x", manu, id); else snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */ break; case 5: if (has_bootrom) snprintf(buf, 32, "RomCRC:%04x", rom_crc); else snprintf(buf, 32, "BootROM: no"); } lcd_puts(0, 1, buf); lcd_update(); button = button_get(true); switch(button) { case BUTTON_STOP: return false; case BUTTON_LEFT: currval--; if(currval < 0) currval = 5; break; case BUTTON_RIGHT: currval++; if(currval > 5) currval = 0; break; } } return false;}#endifbool dbg_partitions(void){ int partition=0; lcd_clear_display(); lcd_puts(0, 0, "Partition"); lcd_puts(0, 1, "list"); lcd_update(); sleep(HZ/2); while(1) { char buf[32]; int button; struct partinfo* p = disk_partinfo(partition); lcd_clear_display(); snprintf(buf, sizeof buf, "P%d: S:%x", partition, p->start); lcd_puts(0, 0, buf); snprintf(buf, sizeof buf, "T:%x %d MB", p->type, p->size / 2048); lcd_puts(0, 1, buf); lcd_update(); button = button_get(true); switch(button) {#ifdef HAVE_RECORDER_KEYPAD case BUTTON_OFF:#else case BUTTON_STOP:#endif return false;#ifdef HAVE_RECORDER_KEYPAD case BUTTON_UP:#endif case BUTTON_LEFT: partition--; if (partition < 0) partition = 3; break; #ifdef HAVE_RECORDER_KEYPAD case BUTTON_DOWN:#endif case BUTTON_RIGHT: partition++; if (partition > 3) partition = 0; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -