# -- coding: utf-8 --
from analyzer import Analyzer
from analyzer import register_analyzer
from analyzer import LogLevel
from .rcc import RCCAnalyzer

class BTIMAnalyzer(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")
        #self.print_reg(HPSYS_RCC)
        
        #以下是根据实例编号需要区分的内容
        #检查时钟与复位
        if (inst_num==1):
            if (HPSYS_RCC.ENR1.BTIM1!=1):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                         "需将HPSYS_RCC的ESR1_BTIM1置1以开启模块时钟")
                inst_error = 1
            if (HPSYS_RCC.RSTR1.BTIM1!=0):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                         "需将HPSYS_RCC的RSTR1_BTIM1置0以释放模块复位")
                inst_error = 1
            tim_clkname = "pclk_hpsys"
        elif (inst_num==2):
            if (HPSYS_RCC.ENR1.BTIM2!=1):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                         "需将HPSYS_RCC的ESR1_BTIM2置1以开启模块时钟")
                inst_error = 1
            if (HPSYS_RCC.RSTR1.BTIM2!=0):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                         "需将HPSYS_RCC的RSTR1_BTIM2置0以释放模块复位")
                inst_error = 1
            tim_clkname = "clk_peri_hpsys"
        elif (inst_num==3):
            HPSYS_AON = self.read_peripheral("hpsys_aon")
            if (HPSYS_AON.ISSR.LP_ACTIVE == 0):
                self.log(LogLevel.ERROR, f"LPSYS处于睡眠状态，无法访问{self.periph_name}",\
                         f"需将LPSYS唤醒后才能访问{self.periph_name}")
                inst_error = 1
                return
            LPSYS_RCC = self.read_peripheral("lpsys_rcc")
            if (LPSYS_RCC.ENR1.BTIM3!=1):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                         "需将LPSYS_RCC的ESR1_BTIM3置1以开启模块时钟")
                inst_error = 1
            if (LPSYS_RCC.RSTR1.BTIM3!=0):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                         "需将LPSYS_RCC的RSTR1_BTIM3置0以释放模块复位")
                inst_error = 1
            tim_clkname = "pclk_lpsys"
        elif (inst_num==4):
            HPSYS_AON = self.read_peripheral("hpsys_aon")
            if (HPSYS_AON.ISSR.LP_ACTIVE == 0):
                self.log(LogLevel.ERROR, f"LPSYS处于睡眠状态，无法访问{self.periph_name}",\
                         f"需将LPSYS唤醒后才能访问{self.periph_name}")
                inst_error = 1
                return
            LPSYS_RCC = self.read_peripheral("lpsys_rcc")
            if (LPSYS_RCC.ENR1.BTIM4!=1):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                         "需将LPSYS_RCC的ESR1_BTIM4置1以开启模块时钟")
                inst_error = 1
            if (LPSYS_RCC.RSTR1.BTIM4!=0):
                self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                         "需将LPSYS_RCC的RSTR1_BTIM4置0以释放模块复位")
                inst_error = 1
            tim_clkname = "pclk_lpsys"
            
        #前置检查结束，如果出错就中止分析
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}上述初始配置发现错误，分析无法继续进行",\
                     "请将上述错误修正后重新启动分析")
            return
        #self.log(LogLevel.INFO, "初始配置分析完成，未发现错误，启动功能分析")
               
        #以下是各实例共同的内容 
        #读取BTIM寄存器
        BTIM = self.read_peripheral(self.periph_name)

        #基本计数信息
        rcc = RCCAnalyzer(self.device,"rcc",self.port,self.baudrate);
        tim_clk, = rcc.get_clk(tim_clkname);
        tim_freq = tim_clk / (BTIM.PSC.PSC + 1);
        tim_period = 1000/tim_freq;
        #打印频率信息
        self.log(LogLevel.INFO, f"源时钟{tim_clkname} {tim_clk}MHz,分频后计数时钟{tim_freq}MHz({tim_period:.1f}ns)")
        #打印计数信息
        if (BTIM.CR1.OPM):
            tim_opm_str = "单次"
        else:
            tim_opm_str = "循环"
        if (BTIM.ARR.ARR == 0):
            self.log(LogLevel.INFO, f"计数值未配置(ARR=0)")
        else:
            tim_cycle = tim_period*(BTIM.ARR.ARR+1)/1000
            self.log(LogLevel.INFO, f"{tim_opm_str}计数0->{BTIM.ARR.ARR},一次完整计数周期{tim_cycle:.3f}us({1000/tim_cycle:.3f}KHz)")
        if (BTIM.CR1.CEN):
            self.log(LogLevel.INFO, f"计数已启动，当前计数值{BTIM.CNT.CNT}")
        else:
            self.log(LogLevel.INFO, f"计数未启动")
            
            
        #输出分析结果
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}配置发现错误",\
                     "请检查配置")
        else:
            self.log(LogLevel.INFO, f"{self.periph_name}分析结束，未发现错误")
        
register_analyzer("BTIM", BTIMAnalyzer)

