summaryrefslogtreecommitdiffstats
path: root/firmware/target/mips/ingenic_jz47xx/debug-jz4760.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/debug-jz4760.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/debug-jz4760.c467
1 files changed, 339 insertions, 128 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/debug-jz4760.c b/firmware/target/mips/ingenic_jz47xx/debug-jz4760.c
index 301f72a12e..567c1798c7 100644
--- a/firmware/target/mips/ingenic_jz47xx/debug-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/debug-jz4760.c
@@ -7,6 +7,7 @@
* \/ \/ \/ \/ \/
*
* Copyright (C) 2018 by Solomon Peachy
+ * Copyright (C) 2020 by William Wilgus
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -31,14 +32,19 @@
#ifndef BOOTLOADER
#include "action.h"
+#include "list.h"
+static bool is_done = false;
static int line = 0;
+static int maxlines = 0;
/*
* Clock Generation Module
*/
-#define TO_MHZ(x) ((x)/1000000), ((x)%1000000)/10000
-#define TO_KHZ(x) ((x)/1000), ((x)%1000)/10
+#define DBG_FREQ_FMT "%s:%3d.%02d %cHz" /*IDSTR, 000 HZ INT, 00HZ FRAC, _/K/M */
+#define TO_MHZ(x) ((x)/1000000), ((x)%1000000)/10000, 'M'
+#define TO_KHZ(x) ((x)/1000), ((x)%1000)/10, 'K'
+
#define DEBUG_CANCEL ACTION_STD_CANCEL
#define DEBUG_NEXT ACTION_STD_NEXT
@@ -50,126 +56,259 @@ static int line = 0;
#define ON "Enabled"
#define OFF "Disabled"
+#define STOPPED "Stopped"
+#define RUNNING "Running"
static bool dbg_btn(bool *done, int *x)
{
bool cont = !*done;
if (cont)
{
- lcd_update();
int button = get_action(CONTEXT_STD,HZ/10);
switch(button)
{
case DEBUG_CANCEL:
*done = true;
+
case DEBUG_NEXT:
cont = false;
case DEBUG_LEFT_JUSTIFY:
- (*x) = 0;
+ if (x){(*x) = 0;}
sleep(HZ/5);
break;
case DEBUG_LEFT_SCROLL:
- (*x)--;
+ if(x){(*x)--;}
+ break;
}
}
+ return cont;
+}
+
+static bool dbg_btn_update(bool *done, int *x)
+{
+ bool cont = !*done;
+ if (cont)
+ {
+ lcd_update();
+ cont = dbg_btn(done, x);
+ }
lcd_clear_display();
return cont;
}
-static void display_clocks(void)
+static inline unsigned int read_cp0_15 (void)
+{
+ /* CPUID Cp0 Register 15 Select 0 */
+ unsigned int cp_val;
+ asm volatile("mfc0 %0, $15\n" : "=r" (cp_val));
+ return (cp_val);
+}
+
+static bool display_clocks(void)
{
unsigned int cppcr0 = REG_CPM_CPPCR0; /* PLL Control Register */
unsigned int cppcr1 = REG_CPM_CPPCR1; /* PLL Control Register */
unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
unsigned int od[4] = {1, 2, 4, 8};
- lcd_putsf(0, line++, "CPPCR0:0x%08x", cppcr0);
- if (cppcr0 & CPPCR0_PLLEN) {
- lcd_putsf(0, line++, "PLL0 :%3d.%02d MHz", TO_MHZ(__cpm_get_pllout()));
- lcd_putsf(0, line++, "m:n:o :%d:%d:%d",
- __cpm_get_pllm(),
- __cpm_get_plln(),
- od[__cpm_get_pllod()]
- );
- }
- lcd_putsf(0, line++, "CPPCR1:0x%08x", cppcr1);
- if (cppcr1 & CPPCR1_PLL1EN) {
- lcd_putsf(0, line++, "PLL1 :%3d.%02d MHz", TO_MHZ(__cpm_get_pll1out()));
- lcd_putsf(0, line++, "m:n:o :%d:%d:%d",
- __cpm_get_pll1m(),
- __cpm_get_pll1n(),
- od[__cpm_get_pll1od()]
- );
+ int x = 0;
+ int cur_item = -1;
+ bool is_last_item = false;
+
+ while(!is_done)
+ {
+ lcd_clear_display();
+
+ if (is_last_item || cur_item < 0)
+ cur_item = 0;
+ else if (cur_item >= 0)
+ cur_item += maxlines;
+
+ is_last_item = false;
+
+ while(dbg_btn(&is_done, &x))
+ {
+ lcd_clear_display();
+ line = 0;
+ switch(cur_item)
+ {
+ case 0:
+ lcd_putsf(x, line++, "[%s]", "Clocks");
+ case 1:
+ lcd_putsf(x, line++, "CPPCR0:0x%08x", cppcr0);
+ case 2:
+ if (cppcr0 & CPPCR0_PLLEN) {
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "PLL0 ",
+ TO_MHZ(__cpm_get_pllout()));
+ lcd_putsf(x, line++, "m:n:o :%d:%d:%d",
+ __cpm_get_pllm(),
+ __cpm_get_plln(),
+ od[__cpm_get_pllod()]
+ );
+ }
+ else if (cur_item == 2)
+ cur_item++;
+ case 3:
+ lcd_putsf(x, line++, "CPPCR1:0x%08x", cppcr1);
+ case 4:
+ if (cppcr1 & CPPCR1_PLL1EN) {
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "PLL1 ",
+ TO_MHZ(__cpm_get_pll1out()));
+ lcd_putsf(x, line++, "m:n:o :%d:%d:%d",
+ __cpm_get_pll1m(),
+ __cpm_get_pll1n(),
+ od[__cpm_get_pll1od()]
+ );
+ }
+ else if (cur_item == 3)
+ cur_item++;
+ case 5:
+ lcd_putsf(x, line++, "C:H:M:P:%d:%d:%d:%d",
+ div[__cpm_get_cdiv()],
+ div[__cpm_get_hdiv()],
+ div[__cpm_get_mdiv()],
+ div[__cpm_get_pdiv()]
+ );
+ case 6:
+ lcd_putsf(x, line++, "I:P:M : %d:%d:%d",
+ __cpm_get_i2sdiv()+1,
+ __cpm_get_pixdiv()+1,
+ __cpm_get_mscdiv()+1
+ );
+ case 7:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "CCLK ",
+ TO_MHZ(__cpm_get_cclk()));
+ case 8:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "HCLK ",
+ TO_MHZ(__cpm_get_hclk()));
+ case 9:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "MCLK ",
+ TO_MHZ(__cpm_get_mclk()));
+ case 10:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "PCLK ",
+ TO_MHZ(__cpm_get_pclk()));
+ case 11:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "PIXCLK ",
+ TO_KHZ(__cpm_get_pixclk()));
+ case 12:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "I2SCLK ",
+ TO_MHZ(__cpm_get_i2sclk()));
+ case 13:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "MSCCLK ",
+ TO_MHZ(__cpm_get_mscclk()));
+ case 14:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "XTALCLK ",
+ TO_MHZ(__cpm_get_extalclk()));
+ case 15:
+ lcd_putsf(x, line++, DBG_FREQ_FMT, "RTCCLK ",
+ TO_KHZ(__cpm_get_rtcclk()));
+ default:
+ if (line <= maxlines + 1)
+ is_last_item = true;
+ }
+ lcd_update();
+ }
}
- lcd_putsf(0, line++, "C:H:M:P:%d:%d:%d:%d",
- div[__cpm_get_cdiv()],
- div[__cpm_get_hdiv()],
- div[__cpm_get_mdiv()],
- div[__cpm_get_pdiv()]
- );
- lcd_putsf(0, line++, "I:P:M : %d:%d:%d",
- __cpm_get_i2sdiv()+1,
- __cpm_get_pixdiv()+1,
- __cpm_get_mscdiv()+1
- );
- lcd_putsf(0, line++, "CCLK :%3d.%02d MHz", TO_MHZ(__cpm_get_cclk()));
- lcd_putsf(0, line++, "HCLK :%3d.%02d MHz", TO_MHZ(__cpm_get_hclk()));
- lcd_putsf(0, line++, "MCLK :%3d.%02d MHz", TO_MHZ(__cpm_get_mclk()));
- lcd_putsf(0, line++, "PCLK :%3d.%02d MHz", TO_MHZ(__cpm_get_pclk()));
- lcd_putsf(0, line++, "PIXCLK:%6d.%02d KHz", TO_KHZ(__cpm_get_pixclk()));
- lcd_putsf(0, line++, "I2SCLK:%3d.%02d MHz", TO_MHZ(__cpm_get_i2sclk()));
- lcd_putsf(0, line++, "MSCCLK:%3d.%02d MHz", TO_MHZ(__cpm_get_mscclk()));
- lcd_putsf(0, line++, "EXTALCLK:%3d.%02d MHz", TO_MHZ(__cpm_get_extalclk()));
- lcd_putsf(0, line++, "RTCCLK:%3d.%02d KHz", TO_KHZ(__cpm_get_rtcclk()));
+ return true;
}
-static void display_enabled_clocks(void)
+static bool display_enabled_clocks(void)
{
unsigned long lcr = REG_CPM_LCR;
unsigned long clkgr0 = REG_CPM_CLKGR0;
+ int x = 0;
+ int cur_item = -1;
+ bool is_last_item = false;
+
+ while(!is_done)
+ {
+ lcd_clear_display();
+
+ if (is_last_item || cur_item < 0)
+ cur_item = 0;
+ else if (cur_item >= 0)
+ cur_item += maxlines;
- lcd_putsf(0, line++, "Low Power Mode : %s",
- ((lcr & LCR_LPM_MASK) == LCR_LPM_IDLE) ?
- "IDLE" : (((lcr & LCR_LPM_MASK) == LCR_LPM_SLEEP) ? "SLEEP" : "HIBERNATE")
- );
-
- lcd_putsf(0, line++, "Doze Mode : %s",
- (lcr & LCR_DOZE) ? "ON" : "OFF");
- if (lcr & LCR_DOZE)
- lcd_putsf(0, line++, " duty : %d", (int)((lcr & LCR_DUTY_MASK) >> LCR_DUTY_LSB));
-
- lcd_putsf(0, line++, "IPU : %s",
- (clkgr0 & CLKGR0_IPU) ? "stopped" : "running");
- lcd_putsf(0, line++, "DMAC : %s",
- (clkgr0 & CLKGR0_DMAC) ? "stopped" : "running");
- lcd_putsf(0, line++, "UHC : %s",
- (clkgr0 & CLKGR0_UHC) ? "stopped" : "running");
- lcd_putsf(0, line++, "LCD : %s",
- (clkgr0 & CLKGR0_LCD) ? "stopped" : "running");
- lcd_putsf(0, line++, "CIM : %s",
- (clkgr0 & CLKGR0_CIM) ? "stopped" : "running");
- lcd_putsf(0, line++, "SADC : %s",
- (clkgr0 & CLKGR0_SADC) ? "stopped" : "running");
- lcd_putsf(0, line++, "MSC0 : %s",
- (clkgr0 & CLKGR0_MSC0) ? "stopped" : "running");
- lcd_putsf(0, line++, "MSC1 : %s",
- (clkgr0 & CLKGR0_MSC1) ? "stopped" : "running");
- lcd_putsf(0, line++, "MSC2 : %s",
- (clkgr0 & CLKGR0_MSC2) ? "stopped" : "running");
- lcd_putsf(0, line++, "AIC : %s",
- (clkgr0 & CLKGR0_AIC) ? "stopped" : "running");
- lcd_putsf(0, line++, "SSI1 : %s",
- (clkgr0 & CLKGR0_SSI1) ? "stopped" : "running");
- lcd_putsf(0, line++, "SSI2 : %s",
- (clkgr0 & CLKGR0_SSI2) ? "stopped" : "running");
- lcd_putsf(0, line++, "I2C0 : %s",
- (clkgr0 & CLKGR0_I2C0) ? "stopped" : "running");
- lcd_putsf(0, line++, "I2C1 : %s",
- (clkgr0 & CLKGR0_I2C1) ? "stopped" : "running");
- lcd_putsf(0, line++, "UART1 : %s",
- (clkgr0 & CLKGR0_UART1) ? "stopped" : "running");
- lcd_putsf(0, line++, "UART0 : %s",
- (clkgr0 & CLKGR0_UART0) ? "stopped" : "running");
+ is_last_item = false;
+
+ while(dbg_btn(&is_done, &x))
+ {
+ lcd_clear_display();
+ line = 0;
+ switch(cur_item)
+ {
+ case 0:
+ lcd_putsf(x, line++, "[%s]", "Enabled Clocks");
+ case 1:
+ lcd_putsf(x, line++, "Low Power Mode : %s",
+ ((lcr & LCR_LPM_MASK) == LCR_LPM_IDLE) ?
+ "IDLE" : (((lcr & LCR_LPM_MASK) == LCR_LPM_SLEEP) ? "SLEEP" : "HIBERNATE")
+ );
+ case 2:
+ lcd_putsf(x, line++, "Doze Mode : %s",
+ (lcr & LCR_DOZE) ? "ON" : "OFF");
+ case 3:
+ if (lcr & LCR_DOZE)
+ lcd_putsf(x, line++, " duty : %d",
+ (int)((lcr & LCR_DUTY_MASK) >> LCR_DUTY_LSB));
+ else if (cur_item == 2)
+ cur_item++;
+ case 4:
+ lcd_putsf(x, line++, "IPU : %s",
+ (clkgr0 & CLKGR0_IPU) ? STOPPED : RUNNING);
+ case 5:
+ lcd_putsf(x, line++, "DMAC : %s",
+ (clkgr0 & CLKGR0_DMAC) ? STOPPED : RUNNING);
+ case 6:
+ lcd_putsf(x, line++, "UHC : %s",
+ (clkgr0 & CLKGR0_UHC) ? STOPPED : RUNNING);
+ case 7:
+ lcd_putsf(x, line++, "LCD : %s",
+ (clkgr0 & CLKGR0_LCD) ? STOPPED : RUNNING);
+ case 8:
+ lcd_putsf(x, line++, "CIM : %s",
+ (clkgr0 & CLKGR0_CIM) ? STOPPED : RUNNING);
+ case 9:
+ lcd_putsf(x, line++, "SADC : %s",
+ (clkgr0 & CLKGR0_SADC) ? STOPPED : RUNNING);
+ case 10:
+ lcd_putsf(x, line++, "MSC0 : %s",
+ (clkgr0 & CLKGR0_MSC0) ? STOPPED : RUNNING);
+ case 11:
+ lcd_putsf(x, line++, "MSC1 : %s",
+ (clkgr0 & CLKGR0_MSC1) ? STOPPED : RUNNING);
+ case 12:
+ lcd_putsf(x, line++, "MSC2 : %s",
+ (clkgr0 & CLKGR0_MSC2) ? STOPPED : RUNNING);
+ case 13:
+ lcd_putsf(x, line++, "AIC : %s",
+ (clkgr0 & CLKGR0_AIC) ? STOPPED : RUNNING);
+ case 14:
+ lcd_putsf(x, line++, "SSI1 : %s",
+ (clkgr0 & CLKGR0_SSI1) ? STOPPED : RUNNING);
+ case 15:
+ lcd_putsf(x, line++, "SSI2 : %s",
+ (clkgr0 & CLKGR0_SSI2) ? STOPPED : RUNNING);
+ case 16:
+ lcd_putsf(x, line++, "I2C0 : %s",
+ (clkgr0 & CLKGR0_I2C0) ? STOPPED : RUNNING);
+ case 17:
+ lcd_putsf(x, line++, "I2C1 : %s",
+ (clkgr0 & CLKGR0_I2C1) ? STOPPED : RUNNING);
+ case 18:
+ lcd_putsf(x, line++, "UART1 : %s",
+ (clkgr0 & CLKGR0_UART1) ? STOPPED : RUNNING);
+ case 19:
+ lcd_putsf(x, line++, "UART0 : %s",
+ (clkgr0 & CLKGR0_UART0) ? STOPPED : RUNNING);
+ default:
+ if (line <= maxlines + 1)
+ is_last_item = true;
+ }
+ lcd_update();
+ }
+ }
+ return true;
}
bool dbg_ports(void)
@@ -191,10 +330,10 @@ bool dbg_ports(void)
while(!done)
{
i = 0;
- while(dbg_btn(&done, &x))
+ while(dbg_btn_update(&done, &x))
{
i %= last_port; /*PORT: A B C D E F */
- while(dbg_btn(&done, &x))
+ while(dbg_btn_update(&done, &x))
{
line = 0;
lcd_puts(x, line++, "[GPIO Vals and Dirs]");
@@ -218,50 +357,11 @@ bool dbg_ports(void)
}
lcd_setfont(FONT_UI);
-#endif
+#endif /* CONFIG_CPU ==JZ4760B */
return false;
}
-extern uint32_t irqstackend,irqstackbegin;
-
-bool dbg_hw_info(void)
-{
- int btn = 0;
-#ifdef HAVE_TOUCHSCREEN
- int touch;
-#endif
- struct tm *cur_time;
-
- lcd_setfont(FONT_SYSFIXED);
- while(btn ^ BUTTON_POWER)
- {
- lcd_clear_display();
- line = 0;
-
- uint32_t *ptr = &irqstackbegin;
- for ( ; ptr < &irqstackend && *ptr == 0xDEADBEEF; ptr++) {}
-
- lcd_putsf(0, line++, "IRQ stack max: %d", (uint32_t)&irqstackend - (uint32_t)ptr);
-
- display_clocks();
- display_enabled_clocks();
-#ifdef HAVE_TOUCHSCREEN
- btn = button_read_device(&touch);
- lcd_putsf(0, line++, "X: %d Y: %d BTN: 0x%X", touch>>16, touch&0xFFFF, btn);
-#else
- btn = button_read_device();
-#endif
- cur_time = get_time();
- lcd_putsf(0, line++, "%02d/%02d/%04d %02d:%02d:%02d", cur_time->tm_mday,
- cur_time->tm_mon, cur_time->tm_year, cur_time->tm_hour,
- cur_time->tm_min, cur_time->tm_sec);
- lcd_update();
- sleep(HZ/16);
- }
- lcd_setfont(FONT_UI);
- return true;
-}
#endif
#ifdef BOOTLOADER
@@ -370,3 +470,114 @@ void serial_dump_data(unsigned char* data, int len)
serial_putc( '\n' );
}
#endif
+
+#ifndef BOOTLOADER
+static const struct {
+ unsigned char *desc; /* string or ID */
+ bool (*function) (void); /* return true if USB was connected */
+} hwinfo_items[] = {
+ { "", NULL }, /*RTC*/
+ { "", NULL }, /*CPUID*/
+ { "", NULL }, /*IRQSTACKMAX*/
+ { "Clocks", display_clocks},
+ { "Enabled Clocks", display_enabled_clocks},
+ { "", NULL}, /*TOUCH/BTN*/
+
+};
+
+static int hw_info_menu_action_cb(int btn, struct gui_synclist *lists)
+{
+ static long last_refresh = 0;
+ int selection = gui_synclist_get_sel_pos(lists);
+ if (btn == ACTION_STD_OK)
+ {
+ FOR_NB_SCREENS(i)
+ viewportmanager_theme_enable(i, false, NULL);
+ if (hwinfo_items[selection].function)
+ {
+ is_done = false;
+ hwinfo_items[selection].function();
+ }
+ btn = ACTION_REDRAW;
+ FOR_NB_SCREENS(i)
+ viewportmanager_theme_undo(i, false);
+ }
+ else if (btn == ACTION_STD_CONTEXT)
+ {
+ }
+ else if (btn == 0 && TIME_AFTER(current_tick, last_refresh + HZ / 2))
+ {
+ last_refresh = current_tick;
+ btn = ACTION_REDRAW;
+ /* to make menu items update */
+ }
+ return btn;
+}
+
+static const char* hw_info_menu_get_name(int item, void * data,
+ char *buffer, size_t buffer_len)
+{
+ (void)data;
+ struct tm *cur_time;
+ uint32_t *stackptr;
+ extern uint32_t irqstackend,irqstackbegin;
+ int btn;
+#ifdef HAVE_TOUCHSCREEN
+ int touch;
+#endif
+
+ switch(item)
+ {
+ /* create your dynamic items here */
+ case 0:/*RTC*/
+ cur_time = get_time();
+ snprintf(buffer, buffer_len, "%02d/%02d/%04d %02d:%02d:%02d",
+ cur_time->tm_mday,cur_time->tm_mon, cur_time->tm_year,
+ cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec);
+ return buffer;
+ case 1: /*cpuID*/
+ snprintf(buffer, buffer_len, "CPUID %X:%d",
+ read_cp0_15(), (REG_CPM_CLKGR0 & BIT31) >> 31);
+ return buffer;
+ case 2: /*IRQstack*/
+ stackptr = &irqstackbegin;
+ for ( ; stackptr < &irqstackend && *stackptr == 0xDEADBEEF; stackptr++) {}
+ snprintf(buffer, buffer_len, "IRQ stack max: %lu",
+ (uint32_t)&irqstackend - (uint32_t)stackptr);
+ return buffer;
+ case 5: /*Touch/BTN*/
+#ifdef HAVE_TOUCHSCREEN
+ btn = button_read_device(&touch);
+ snprintf(buffer, buffer_len, "X: %d Y: %d BTN: 0x%X",
+ touch>>16, touch&0xFFFF, btn);
+#else
+ btn = button_read_device();
+ snprintf(buffer, buffer_len, "BTN: 0x%X", btn);
+#endif
+ return buffer;
+ default: /* static items -- default */
+ return hwinfo_items[item].desc;
+ }
+ return "???";
+}
+
+static int hw_info_debug_menu(void)
+{
+ int h;
+ lcd_setfont(FONT_SYSFIXED);
+ lcd_getstringsize((unsigned char *)"A", NULL, &h);
+ maxlines = LCD_HEIGHT / h - 1;
+ is_done = false;
+ struct simplelist_info info;
+
+ simplelist_info_init(&info, "Hw Info", ARRAYLEN(hwinfo_items), NULL);
+ info.action_callback = hw_info_menu_action_cb;
+ info.get_name = hw_info_menu_get_name;
+ return (simplelist_show_list(&info)) ? 1 : 0;
+}
+
+bool dbg_hw_info(void)
+{
+ return hw_info_debug_menu() > 0;
+}
+#endif