rockbox/firmware/target/arm/imx233/debug-imx233.c
Amaury Pouly bdc572b8a1 imx233: improve debug and fix for stmp3600 and stmp3700
Add pwm and usb screen, fix charging, icoll and dcp on other
stmps.

Change-Id: I3cddf987e178bc01046132adaed15cff750835c9
2013-06-17 00:29:25 +02:00

724 lines
22 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 by Amaury Pouly
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "dma-imx233.h"
#include "action.h"
#include "lcd.h"
#include "font.h"
#include "adc.h"
#include "adc-imx233.h"
#include "power-imx233.h"
#include "clkctrl-imx233.h"
#include "powermgmt-imx233.h"
#include "rtc-imx233.h"
#include "dcp-imx233.h"
#include "pinctrl-imx233.h"
#include "ocotp-imx233.h"
#include "pwm-imx233.h"
#include "string.h"
#include "stdio.h"
#define DEBUG_CANCEL BUTTON_BACK
static struct
{
const char *name;
unsigned chan;
} dbg_channels[] =
{
{ "i2c", APB_I2C },
{ "dac", APB_AUDIO_DAC },
{ "ssp1", APB_SSP(1) },
{ "ssp2", APB_SSP(2) },
};
static struct
{
const char *name;
unsigned src;
} dbg_irqs[] =
{
{ "vdd5v", INT_SRC_VDD5V },
{ "dac_dma", INT_SRC_DAC_DMA },
{ "dac_err", INT_SRC_DAC_ERROR },
{ "adc_dma", INT_SRC_ADC_DMA },
{ "adc_err", INT_SRC_ADC_ERROR },
{ "usbctrl", INT_SRC_USB_CTRL },
{ "ssp1_dma", INT_SRC_SSP1_DMA },
{ "ssp1_err", INT_SRC_SSP1_ERROR },
{ "gpio0", INT_SRC_GPIO0 },
{ "gpio1", INT_SRC_GPIO1 },
{ "gpio2", INT_SRC_GPIO2 },
#if IMX233_SUBTARGET >= 3780
{ "ssp2_dma", INT_SRC_SSP2_DMA },
{ "ssp2_err", INT_SRC_SSP2_ERROR },
{ "lcdif_dma", INT_SRC_LCDIF_DMA },
{ "lcdif_err", INT_SRC_LCDIF_ERROR },
{ "dcp", INT_SRC_DCP },
#endif
{ "i2c_dma", INT_SRC_I2C_DMA },
{ "i2c_err", INT_SRC_I2C_ERROR },
{ "timer0", INT_SRC_TIMER(0) },
{ "timer1", INT_SRC_TIMER(1) },
{ "timer2", INT_SRC_TIMER(2) },
{ "timer3", INT_SRC_TIMER(3) },
{ "touch_det", INT_SRC_TOUCH_DETECT },
{ "lradc_ch0", INT_SRC_LRADC_CHx(0) },
{ "lradc_ch1", INT_SRC_LRADC_CHx(1) },
{ "lradc_ch2", INT_SRC_LRADC_CHx(2) },
{ "lradc_ch3", INT_SRC_LRADC_CHx(3) },
{ "lradc_ch4", INT_SRC_LRADC_CHx(4) },
{ "lradc_ch5", INT_SRC_LRADC_CHx(5) },
{ "lradc_ch6", INT_SRC_LRADC_CHx(6) },
{ "lradc_ch7", INT_SRC_LRADC_CHx(7) },
{ "rtc_1msec", INT_SRC_RTC_1MSEC },
};
bool dbg_hw_info_dma(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 25);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
lcd_putsf(0, 0, "S C name bar apb ahb una");
for(unsigned i = 0; i < ARRAYLEN(dbg_channels); i++)
{
struct imx233_dma_info_t info = imx233_dma_get_info(dbg_channels[i].chan, DMA_INFO_ALL);
lcd_putsf(0, i + 1, "%c %c %4s %8x %3x %3x %3x",
info.gated ? 'g' : info.freezed ? 'f' : ' ',
!info.int_enabled ? '-' : info.int_error ? 'e' : info.int_cmdcomplt ? 'c' : ' ',
dbg_channels[i].name, info.bar, info.apb_bytes, info.ahb_bytes,
info.nr_unaligned);
}
lcd_update();
yield();
}
}
bool dbg_hw_info_power(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
struct imx233_power_info_t info = imx233_power_get_info(POWER_INFO_ALL);
int line = 0;
unsigned trg, bo;
bool en;
int linreg;
char buf[16];
lcd_putsf(0, line++, "name value bo linreg");
#define DISP_REGULATOR(name) \
imx233_power_get_regulator(REGULATOR_##name, &trg, &bo); \
imx233_power_get_regulator_linreg(REGULATOR_##name, &en, &linreg); \
if(en) snprintf(buf, sizeof(buf), "%d", linreg); \
else snprintf(buf, sizeof(buf), " "); \
lcd_putsf(0, line++, "%6s %4d %4d %s", #name, trg, bo, buf); \
DISP_REGULATOR(VDDD);
#if IMX233_SUBTARGET >= 3700
DISP_REGULATOR(VDDA);
DISP_REGULATOR(VDDIO);
#endif
#if IMX233_SUBTARGET >= 3780
DISP_REGULATOR(VDDMEM);
#endif
lcd_putsf(0, line++, "DC-DC: pll: %d freq: %d", info.dcdc_sel_pllclk, info.dcdc_freqsel);
lcd_putsf(0, line++, "charge: %d mA stop: %d mA", info.charge_current, info.stop_current);
lcd_putsf(0, line++, "charging: %d bat_adj: %d", info.charging, info.batt_adj);
lcd_putsf(0, line++, "4.2: en: %d dcdc: %d", info._4p2_enable, info._4p2_dcdc);
lcd_putsf(0, line++, "4.2: cmptrip: %d dropout: %d", info._4p2_cmptrip, info._4p2_dropout);
lcd_putsf(0, line++, "5V: pwd_4.2_charge: %d", info._5v_pwd_charge_4p2);
lcd_putsf(0, line++, "5V: chargelim: %d mA", info._5v_charge_4p2_limit);
lcd_putsf(0, line++, "5V: dcdc: %d xfer: %d", info._5v_enable_dcdc, info._5v_dcdc_xfer);
lcd_putsf(0, line++, "5V: thr: %d mV use: %d cmps: %d", info._5v_vbusvalid_thr,
info._5v_vbusvalid_detect, info._5v_vbus_cmps);
lcd_update();
yield();
}
}
bool dbg_hw_info_adc(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 25);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
/* add battery readout in mV, this it is not the direct output of a channel */
lcd_putsf(0, 0, "Battery(mV) %d", _battery_voltage());
for(unsigned i = 0; i < NUM_ADC_CHANNELS; i++)
{
lcd_putsf(0, i + 1, "%s %d", imx233_adc_channel_name[i],
adc_read(i));
}
lcd_update();
yield();
}
}
static struct
{
enum imx233_clock_t clk;
const char *name;
bool has_enable;
bool has_bypass;
bool has_idiv;
bool has_fdiv;
bool has_freq;
} dbg_clk[] =
{
{ CLK_PLL, "pll", true, false, false, false, true},
{ CLK_XTAL, "xtal", false, false, false, false, true},
{ CLK_PIX, "pix", true, true, true, true, true },
{ CLK_SSP, "ssp", true, true, true, false, true },
{ CLK_IO, "io", false, false, false, true, true },
{ CLK_CPU, "cpu", false, true, true, true, true },
{ CLK_HBUS, "hbus", false, false, true, true, true },
{ CLK_EMI, "emi", false, true, true, true, true },
{ CLK_XBUS, "xbus", false, false, true, false, true }
};
bool dbg_hw_info_clkctrl(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
/* 012345678901234567890123456789 */
lcd_putsf(0, 0, "name en by idiv fdiv frequency");
for(unsigned i = 0; i < ARRAYLEN(dbg_clk); i++)
{
#define c dbg_clk[i]
lcd_putsf(0, i + 1, "%4s", c.name);
if(c.has_enable)
lcd_putsf(5, i + 1, "%2d", imx233_clkctrl_is_enabled(c.clk));
if(c.has_bypass)
lcd_putsf(8, i + 1, "%2d", imx233_clkctrl_get_bypass(c.clk));
if(c.has_idiv && imx233_clkctrl_get_div(c.clk) != 0)
lcd_putsf(10, i + 1, "%4d", imx233_clkctrl_get_div(c.clk));
if(c.has_fdiv && imx233_clkctrl_get_frac_div(c.clk) != 0)
lcd_putsf(16, i + 1, "%4d", imx233_clkctrl_get_frac_div(c.clk));
if(c.has_freq)
lcd_putsf(21, i + 1, "%9d", imx233_clkctrl_get_freq(c.clk));
#undef c
}
int line = ARRAYLEN(dbg_clk) + 1;
if(!imx233_clkctrl_is_auto_slow_enabled())
lcd_putsf(0, line++, "auto-slow: disabled");
else
lcd_putsf(0, line++, "auto-slow: 1/%d", 1 << imx233_clkctrl_get_auto_slow_div());
lcd_update();
yield();
}
}
bool dbg_hw_info_powermgmt(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
struct imx233_powermgmt_info_t info = imx233_powermgmt_get_info();
lcd_putsf(0, 0, "state: %s",
info.state == DISCHARGING ? "discharging" :
#if CONFIG_CHARGING >= CHARGING_MONITOR
info.state == CHARGE_STATE_DISABLED ? "disabled" :
info.state == CHARGE_STATE_ERROR ? "error" :
#endif
#if CONFIG_CHARGING >= CHARGING_MONITOR
info.state == TRICKLE ? "trickle" :
info.state == TOPOFF ? "topoff" :
info.state == CHARGING ? "charging" :
#endif
"<unknown>");
lcd_putsf(0, 1, "charging tmo: %d", info.charging_timeout);
lcd_putsf(0, 2, "topoff tmo: %d", info.topoff_timeout);
lcd_putsf(0, 3, "4p2ilimit tmo: %d", info.incr_4p2_ilimit_timeout);
lcd_update();
yield();
}
}
bool dbg_hw_info_rtc(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
struct imx233_rtc_info_t info = imx233_rtc_get_info();
lcd_putsf(0, 0, "seconds: %lu", info.seconds);
for(int i = 0; i < 6; i++)
lcd_putsf(0, i + 1, "persistent%d: 0x%lx", i, info.persistent[i]);
lcd_update();
yield();
}
}
#if IMX233_SUBTARGET >= 3780
bool dbg_hw_info_dcp(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
struct imx233_dcp_info_t info = imx233_dcp_get_info(DCP_INFO_ALL);
lcd_putsf(0, 0, "crypto: %d csc: %d", info.has_crypto, info.has_csc);
lcd_putsf(0, 1, "keys: %d channels: %d", info.num_keys, info.num_channels);
lcd_putsf(0, 2, "ciphers: 0x%lx hash: 0x%lx", info.ciphers, info.hashs);
lcd_putsf(0, 3, "gather wr: %d otp rdy: %d ch0merged: %d",
info.gather_writes, info.otp_key_ready, info.ch0_merged);
lcd_putsf(0, 4, "ctx switching: %d caching: %d", info.context_switching,
info.context_caching);
lcd_putsf(0, 5, "ch irq ien en rdy pri sem cmdptr a");
int nr = HW_DCP_NUM_CHANNELS;
for(int i = 0; i < nr; i++)
{
lcd_putsf(0, 6 + i, "%d %d %d %d %d %d %d 0x%08lx %d",
i, info.channel[i].irq, info.channel[i].irq_en, info.channel[i].enable,
info.channel[i].ready, info.channel[i].high_priority,
info.channel[i].sema, info.channel[i].cmdptr, info.channel[i].acquired);
}
lcd_putsf(0, 6 + nr, "csc %d %d %d %d",
info.csc.irq, info.csc.irq_en, info.csc.enable, info.csc.priority);
lcd_update();
yield();
}
}
#else
bool dbg_hw_info_dcp(void)
{
return true;
}
#endif
bool dbg_hw_info_icoll(void)
{
lcd_setfont(FONT_SYSFIXED);
int first_irq = 0;
int dbg_irqs_count = sizeof(dbg_irqs) / sizeof(dbg_irqs[0]);
int line_count = lcd_getheight() / font_get(lcd_getfont())->height;
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
first_irq++;
if(first_irq >= dbg_irqs_count)
first_irq = dbg_irqs_count - 1;
break;
case ACTION_STD_PREV:
first_irq--;
if(first_irq < 0)
first_irq = 0;
break;
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
for(int i = first_irq, j = 0; i < dbg_irqs_count && j < line_count; i++, j++)
{
struct imx233_icoll_irq_info_t info = imx233_icoll_get_irq_info(dbg_irqs[i].src);
lcd_putsf(0, j, "%s", dbg_irqs[i].name);
if(info.enabled || info.freq > 0)
lcd_putsf(10, j, "%d", info.freq);
}
lcd_update();
yield();
}
}
bool dbg_hw_info_pinctrl(void)
{
lcd_setfont(FONT_SYSFIXED);
#ifdef IMX233_PINCTRL_DEBUG
unsigned top_user = 0;
#endif
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
#ifdef IMX233_PINCTRL_DEBUG
top_user++;
break;
#endif
case ACTION_STD_PREV:
#ifdef IMX233_PINCTRL_DEBUG
if(top_user > 0)
top_user--;
break;
#endif
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
for(int i = 0; i < 4; i++)
lcd_putsf(0, i, "DIN%d = 0x%08x", i, HW_PINCTRL_DINn(i));
#ifdef IMX233_PINCTRL_DEBUG
unsigned cur_line = 6;
unsigned last_line = lcd_getheight() / font_get(lcd_getfont())->height;
unsigned cur_idx = 0;
for(int bank = 0; bank < 4; bank++)
for(int pin = 0; pin < 32; pin++)
{
const char *owner = imx233_pinctrl_blame(bank, pin);
if(owner == NULL)
continue;
if(cur_idx++ >= top_user && cur_line < last_line)
lcd_putsf(0, cur_line++, "B%dP%02d %s", bank, pin, owner);
}
if(cur_idx < top_user)
top_user = cur_idx - 1;
#endif
lcd_update();
yield();
}
}
#if IMX233_SUBTARGET >= 3700
struct
{
const char *name;
volatile uint32_t *addr;
} dbg_ocotp[] =
{
#define E(n,v) { .name = n, .addr = &v }
E("CUST0", HW_OCOTP_CUSTn(0)), E("CUST1", HW_OCOTP_CUSTn(1)),
E("CUST2", HW_OCOTP_CUSTn(2)), E("CUST0", HW_OCOTP_CUSTn(3)),
E("HWCAP0", HW_OCOTP_HWCAPn(0)), E("HWCAP1", HW_OCOTP_HWCAPn(1)),
E("HWCAP2", HW_OCOTP_HWCAPn(2)), E("HWCAP3", HW_OCOTP_HWCAPn(3)),
E("HWCAP4", HW_OCOTP_HWCAPn(4)), E("HWCAP5", HW_OCOTP_HWCAPn(5)),
E("SWCAP", HW_OCOTP_SWCAP), E("CUSTCAP", HW_OCOTP_CUSTCAP),
E("OPS0", HW_OCOTP_OPSn(0)), E("OPS1", HW_OCOTP_OPSn(1)),
E("OPS2", HW_OCOTP_OPSn(2)), E("OPS2", HW_OCOTP_OPSn(3)),
E("UN0", HW_OCOTP_UNn(0)), E("UN1", HW_OCOTP_UNn(1)),
E("UN2", HW_OCOTP_UNn(2)),
E("ROM0", HW_OCOTP_ROMn(0)), E("ROM1", HW_OCOTP_ROMn(1)),
E("ROM2", HW_OCOTP_ROMn(2)), E("ROM3", HW_OCOTP_ROMn(3)),
E("ROM4", HW_OCOTP_ROMn(4)), E("ROM5", HW_OCOTP_ROMn(5)),
E("ROM6", HW_OCOTP_ROMn(6)), E("ROM7", HW_OCOTP_ROMn(7)),
};
bool dbg_hw_info_ocotp(void)
{
lcd_setfont(FONT_SYSFIXED);
unsigned top_user = 0;
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
top_user++;
break;
case ACTION_STD_PREV:
if(top_user > 0)
top_user--;
break;
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
unsigned cur_line = 0;
unsigned last_line = lcd_getheight() / font_get(lcd_getfont())->height;
unsigned i = 0;
for(i = 0; i < ARRAYLEN(dbg_ocotp); i++)
{
if(i >= top_user && cur_line < last_line)
{
lcd_putsf(0, cur_line, "%s", dbg_ocotp[i].name);
lcd_putsf(8, cur_line++, "%x", imx233_ocotp_read(dbg_ocotp[i].addr));
}
}
if(i < top_user)
top_user = i - 1;
lcd_update();
yield();
}
}
#else
bool dbg_hw_info_ocotp(void)
{
return true;
}
#endif
bool dbg_hw_info_pwm(void)
{
lcd_setfont(FONT_SYSFIXED);
bool detailled_view = false;
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
case ACTION_STD_PREV:
detailled_view = !detailled_view;
break;
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
int line = 0;
if(detailled_view)
lcd_putsf(0, line++, "c cdiv period active/x inactive");
else
lcd_putsf(0, line++, "pwm");
for(int i = 0; i < IMX233_PWM_NR_CHANNELS; i++)
{
struct imx233_pwm_info_t info = imx233_pwm_get_info(i);
if(!info.enabled)
continue;
if(detailled_view)
{
lcd_putsf(0, line++, "%d %4d %6d %6d/%c %6d/%c", i, info.cdiv,
info.period, info.active, info.active_state,
info.inactive, info.inactive_state);
}
else
{
char *prefix = "";
int freq = imx233_clkctrl_get_freq(CLK_XTAL) * 1000 / info.cdiv / info.period;
if(freq > 1000)
{
prefix = "K";
freq /= 1000;
}
int duty = (info.inactive - info.active) * 100 / info.period;
lcd_putsf(0, line++, "%d @%d %sHz, %d%% %c/%c", i, freq, prefix,
duty, info.active_state, info.inactive_state);
}
}
lcd_update();
yield();
}
}
bool dbg_hw_info_usb(void)
{
lcd_setfont(FONT_SYSFIXED);
while(1)
{
int button = get_action(CONTEXT_STD, HZ / 10);
switch(button)
{
case ACTION_STD_NEXT:
BF_SET(USBPHY_CTRL, ENOTGIDDETECT);
BF_SET(USBPHY_CTRL, ENDEVPLUGINDETECT);
break;
case ACTION_STD_PREV:
BF_CLR(USBPHY_CTRL, ENOTGIDDETECT);
BF_CLR(USBPHY_CTRL, ENDEVPLUGINDETECT);
break;
case ACTION_STD_OK:
case ACTION_STD_MENU:
lcd_setfont(FONT_UI);
return true;
case ACTION_STD_CANCEL:
lcd_setfont(FONT_UI);
return false;
}
lcd_clear_display();
int line = 0;
lcd_putsf(0, line++, "VBUS valid: %d/%d", BF_RD(POWER_STS, VBUSVALID), BF_RD(POWER_STS, VBUSVALID_STATUS));
lcd_putsf(0, line++, "A valid: %d/%d", BF_RD(POWER_STS, AVALID), BF_RD(POWER_STS, AVALID_STATUS));
lcd_putsf(0, line++, "B valid: %d/%d", BF_RD(POWER_STS, BVALID), BF_RD(POWER_STS, BVALID_STATUS));
lcd_putsf(0, line++, "session end: %d", BF_RD(POWER_STS, SESSEND));
lcd_putsf(0, line++, "dev plugin: %d", BF_RD(USBPHY_STATUS, DEVPLUGIN_STATUS));
lcd_putsf(0, line++, "OTG ID: %d", BF_RD(USBPHY_STATUS, OTGID_STATUS));
lcd_update();
yield();
}
}
bool dbg_hw_info(void)
{
return dbg_hw_info_clkctrl() && dbg_hw_info_dma() && dbg_hw_info_adc() &&
dbg_hw_info_power() && dbg_hw_info_powermgmt() && dbg_hw_info_rtc() &&
dbg_hw_info_dcp() && dbg_hw_info_pinctrl() && dbg_hw_info_icoll() &&
dbg_hw_info_ocotp() && dbg_hw_info_pwm() && dbg_hw_info_usb() &&
dbg_hw_target_info();
}
bool dbg_ports(void)
{
return false;
}