# -- coding: utf-8 --
#from xml.etree.ElementPath import prepare_self

from analyzer import Analyzer
from analyzer import register_analyzer
from analyzer import LogLevel
from .rcc import RCCAnalyzer

ADC_CH = {28,29,30,31,32,33,34}

class GPADCAnalyzer(Analyzer):
    def run(self):
        super().run()
        self.log(LogLevel.INFO, f"{self.periph_name}分析启动")
        #inst_num = self.get_instance_num(self.periph_name)
        inst_error = 0
        
        #前置检查开始，如果出错就需要中止分析，以防读寄存器卡死或出现非法值
        HPSYS_RCC = self.read_peripheral("hpsys_rcc")
        HPSYS_CFG = self.read_peripheral("hpsys_cfg")
        #self.print_reg(HPSYS_CFG)
        
        #以下是根据实例编号需要区分的内容
        #检查时钟与复位
        if (HPSYS_RCC.ENR2.GPADC!=1):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",
                    "需将HPSYS_RCC的ENR2_GPADC置1以开启模块时钟")
            inst_error = 1
        if (HPSYS_RCC.RSTR2.GPADC!=0):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",
                         "需将HPSYS_RCC的RSTR2_GPADC置0以释放模块复位")
            inst_error = 1


        #前置检查结束，如果出错就中止分析
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}上述初始配置发现错误，分析无法继续进行",\
                     "请将上述错误修正后重新启动分析")
            return
        #self.log(LogLevel.INFO, "初始配置分析完成，未发现错误，启动功能分析")

        #读取GPADC寄存器
        GPADC = self.read_peripheral(self.periph_name)
        #self.print_reg(GPADC)

        #PINMUX检查
        HPSYS_PINMUX = self.read_peripheral("hpsys_pinmux")
        #SLOT PINMUX检查
        for slot_num in range(8):
            slot_en = GPADC.__dict__[f"ADC_SLOT{slot_num}_REG"].SLOT_EN
            psel = GPADC.__dict__[f"ADC_SLOT{slot_num}_REG"].PCHNL_SEL
            if(slot_en and psel!=7):
                self.log(LogLevel.INFO, f"Slot{slot_num}使能，配置到CH{psel}，对应PAD_PA{ADC_CH[psel]:02d}")
                if (HPSYS_PINMUX.__dict__[f"PAD_PA{ADC_CH[psel]:02d}"].FSEL != 7):
                    self.log(LogLevel.ERROR, f"ADC CH配置错误，未选择GPADC功能",\
                         f"应将HPSYS_PINMUX->PAD_PA{ADC_CH[psel]:02d}.FSEL设为7")
                    inst_error = 1

                if ((HPSYS_PINMUX.__dict__[f"PAD_PA{ADC_CH[psel]:02d}"].PE == 1)):
                     self.log(LogLevel.ERROR, f"ADC CHANNEL内部上下拉开启，测量会出错",\
                        f"应将HPSYS_PINMUX->PAD_PA{ADC_CH[psel]:02d}.PE设为0以关闭内部上下拉电阻")
                     inst_error = 1
            elif(slot_en and psel==7):
                self.log(LogLevel.INFO, f"Slot{slot_num}使能，配置到电池电压测量")
                # 检测测电池电压的设置
                if (HPSYS_CFG.ANAU_CR.EN_VBAT_MON != 1):
                    self.log(LogLevel.INFO, f"电池通路没有打开", \
                            f"测电池电压时应将HPSYS_CFG.ANAU_CR.EN_VBAT_MON设为1")

        #检查GPADC电路状态
        if(HPSYS_CFG.ANAU_CR.EN_BG !=1):
            self.log(LogLevel.ERROR, f"Bandgap 没有打开",
                     f"GPADC工作时应将HPSYS_CFG.ANAU_CR.EN_BG设为1")
            inst_error = 1
        if(GPADC.ADC_CFG_REG1.ANAU_GPADC_LDOREF_EN !=1):
            self.log(LogLevel.WARN, f"GPADC参考电压没有打开",
                     f"GPADC工作时应将PADC.ADC_CFG_REG1.ANAU_GPADC_LDOREF_EN设为1")

        #检查GPADC电路设置
        if(GPADC.ADC_CFG_REG1.ANAU_GPADC_MUTE ==1):
            self.log(LogLevel.ERROR, f"MUTE模式已打开",
                     f"GPADC工作时应将GPADC.ADC_CFG_REG1.ANAU_GPADC_MUTE设为0")
        if (GPADC.ADC_CFG_REG1.ANAU_GPADC_P_INT_EN == 1):
            self.log(LogLevel.ERROR, f"P_INT_EN设置错误",
                    f"GPADC工作时应将GPADC.ADC_CFG_REG1.ANAU_GPADC_P_INT_EN设为0")
            inst_error = 1
        if(GPADC.ADC_CFG_REG1.ANAU_GPADC_SE !=1):
            self.log(LogLevel.WARN, f"GPADC处于差分输入模式")

        #检查GPADC时钟频率
        conv_width=GPADC.ADC_CTRL_REG2.CONV_WIDTH
        samp_width=GPADC.ADC_CTRL_REG2.SAMP_WIDTH
        data_dly  =GPADC.ADC_CTRL_REG.DATA_SAMP_DLY

        rcc = RCCAnalyzer(self.device,"rcc",self.port,self.baudrate);
        pclk_freq, = rcc.get_clk("pclk_hpsys");

        gpadc_freq=pclk_freq/(conv_width+samp_width+data_dly+2)*1000
        self.log(LogLevel.INFO, f"GPADC 采样频率为{gpadc_freq:.0f}KHz")
        if(gpadc_freq>4000):
            self.log(LogLevel.ERROR, f"采样频率超过4MHz最高采样频率",
                     f"请重新配置采样频率")
        #检查GPADC DMA设置
        if(GPADC.ADC_CTRL_REG.DMA_EN==1):
            self.log(LogLevel.INFO, f"DMA接口使能")
        else:
            self.log(LogLevel.INFO, f"DMA接口未使能")

        if ((GPADC.ADC_CTRL_REG.DMA_EN == 1) and (GPADC.ADC_CTRL_REG.ADC_OP_MODE==0)):
            self.log(LogLevel.WARN, f"GPADC的DMA使能且处于单次采样模式",
                     f"如果使用DMA取数，GPADC应工作在连续采样模式，即ADC_OP_MODE设为1")
            if(GPADC.ADC_CTRL_REG.DMA_DATA_SEL == 1):
                self.log(LogLevel.ERROR, f"DMA数据源选择错误",
                         f"正常使用时DMA_DATA_SEL应设为0")
                inst_error = 1

        #检查timer trigger
        if(GPADC.ADC_CTRL_REG.TIMER_TRIG_EN==0) :
            self.log(LogLevel.INFO, f"当前没有使能Timer 触发")
        else:
            self.log(LogLevel.INFO, f"Timer 触发已使能，请确认TIMER_TRIG_SRC_SEL和TIMER_TRIG_TYP设置")

        #输出分析结果
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}配置发现错误",\
                     "请检查配置")
        else:
            self.log(LogLevel.INFO, f"{self.periph_name}分析结束，未发现错误")
        
register_analyzer("GPADC", GPADCAnalyzer)

