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

pa_pinmux = (("GPIO","LCDC1_SPI_RSTB","NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"LCDC1_8080_RSTB","NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","LCDC1_SPI_TE"  ,"NONE"    ,"I2S1_MCLK","I2C/UART","TIM","LCDC1_JDI_B2"  ,"LCDC1_8080_TE"  ,"NONE","DBG_DO0"    ),\
             ("GPIO","LCDC1_SPI_CS"  ,"NONE"    ,"I2S1_SDO" ,"I2C/UART","TIM","LCDC1_JDI_B1"  ,"LCDC1_8080_CS"  ,"NONE","DBG_DO1"    ),\
             ("GPIO","LCDC1_SPI_CLK" ,"NONE"    ,"I2S1_SDI" ,"I2C/UART","TIM","LCDC1_JDI_G1"  ,"LCDC1_8080_WR"  ,"NONE","DBG_DO2"    ),\
             ("GPIO","LCDC1_SPI_DIO0","NONE"    ,"I2S1_BCK" ,"I2C/UART","TIM","LCDC1_JDI_R1"  ,"LCDC1_8080_RD"  ,"NONE","DBG_DO3"    ),\
             ("GPIO","LCDC1_SPI_DIO1","NONE"    ,"I2S1_LRCK","I2C/UART","TIM","LCDC1_JDI_HXT" ,"LCDC1_8080_DC"  ,"NONE","DBG_DO4"    ),\
             ("GPIO","LCDC1_SPI_DIO2","NONE"    ,"PDM1_CLK" ,"I2C/UART","TIM","LCDC1_JDI_ENB" ,"LCDC1_8080_DIO0","NONE","DBG_DO5"    ),\
             ("GPIO","LCDC1_SPI_DIO3","NONE"    ,"PDM1_DATA","I2C/UART","TIM","LCDC1_JDI_VST" ,"LCDC1_8080_DIO1","NONE","DBG_DO6"    ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","DBG_DO7"    ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","AUD_CLK_EXT"),\
             ("GPIO","MPI2_CS"       ,"SD1_DIO2","NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","MPI2_DIO1"     ,"SD1_DIO3","NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","MPI2_DIO2"     ,"SD1_CLK" ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","MPI2_DIO0"     ,"SD1_CMD" ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","MPI2_CLK"      ,"SD1_DIO0","NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","MPI2_DIO3"     ,"SD1_DIO1","NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SWDIO"   ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SWCLK"   ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","DBG_CLK"    ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"PDM1_CLK" ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"PDM1_DATA","I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI1_DIO","I2S1_MCLK","I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI1_DI" ,"I2S1_SDO" ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI1_CLK","I2S1_SDI" ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI1_CS" ,"I2S1_BCK" ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"I2S1_LRCK","I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","DBG_DO8"    ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI2_DIO","NONE"     ,"I2C/UART","TIM","NONE"          ,"LCDC1_8080_DIO2","NONE","DBG_DO9"    ),\
             ("GPIO","NONE"          ,"SPI2_DI" ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","NONE"       ),\
             ("GPIO","NONE"          ,"SPI2_CLK","NONE"     ,"I2C/UART","TIM","LCDC1_JDI_VCK" ,"LCDC1_8080_DIO3","NONE","DBG_DO10"   ),\
             ("GPIO","NONE"          ,"SPI2_CS" ,"NONE"     ,"I2C/UART","TIM","LCDC1_JDI_XRST","LCDC1_8080_DIO4","NONE","DBG_DO11"   ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","LCDC1_JDI_HCK" ,"LCDC1_8080_DIO5","NONE","DBG_DO12"   ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","LCDC1_JDI_R2"  ,"LCDC1_8080_DIO6","NONE","DBG_DO13"   ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","LCDC1_JDI_G2"  ,"LCDC1_8080_DIO7","NONE","DBG_DO14"   ),\
             ("GPIO","NONE"          ,"NONE"    ,"NONE"     ,"I2C/UART","TIM","NONE"          ,"NONE"           ,"NONE","DBG_DO15"   ) \
             )


class HpsysGPIOAnalyzer(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_CFG)
        
        #检查时钟与复位
        if (HPSYS_RCC.ENR2.GPIO1!=1):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                     "需将HPSYS_RCC的ESR2_GPIO1置1以开启模块时钟")
            inst_error = 1
        if (HPSYS_RCC.RSTR2.GPIO1!=0):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                     "需将HPSYS_RCC的RSTR2_GPIO1置0以释放模块复位")
            inst_error = 1
        if (HPSYS_RCC.ENR1.PINMUX1!=1):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                     "需将HPSYS_RCC的ESR1_PINMUX1置1以开启模块时钟")
            inst_error = 1
        if (HPSYS_RCC.RSTR1.PINMUX1!=0):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                     "需将HPSYS_RCC的RSTR1_PINMUX1置0以释放模块复位")
            inst_error = 1
        if (HPSYS_RCC.ENR1.SYSCFG1!=1):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块时钟未开启",\
                     "需将HPSYS_RCC的ESR1_SYSCFG1置1以开启模块时钟")
            inst_error = 1
        if (HPSYS_RCC.RSTR1.SYSCFG1!=0):
            self.log(LogLevel.ERROR, f"{self.periph_name}模块被复位",\
                     "需将HPSYS_RCC的RSTR1_SYSCFG1置0以释放模块复位")
            inst_error = 1
            
        #前置检查结束，如果出错就中止分析
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}上述初始配置发现错误，分析无法继续进行",\
                     "请将上述错误修正后重新启动分析")
            return
        #self.log(LogLevel.INFO, "初始配置分析完成，未发现错误，启动功能分析")

        #GPIO检查
        HPSYS_PINMUX = self.read_peripheral("hpsys_pinmux")
        HPSYS_GPIO = self.read_peripheral("hpsys_gpio")
        for i in range(0,45):
            pin_fsel = HPSYS_PINMUX.__dict__[f"PAD_PA{i:02d}"].FSEL
            pin_ie   = HPSYS_PINMUX.__dict__[f"PAD_PA{i:02d}"].IE
            pin_pe   = HPSYS_PINMUX.__dict__[f"PAD_PA{i:02d}"].PE
            pin_ps   = HPSYS_PINMUX.__dict__[f"PAD_PA{i:02d}"].PS
            pin_out_str = ""
            if (pin_fsel>9):
                pin_function = "NONE"
            else:
                pin_function = pa_pinmux[i][pin_fsel];
            #input status
            if (pin_ie):
                if (i<32):
                    pin_in = (HPSYS_GPIO.DIR0.value >> i) & 1;
                else:
                    pin_in = (HPSYS_GPIO.DIR1.value >> (i-32)) & 1;
                if (pin_in):
                    pin_in_str = "输入为高"
                else:
                    pin_in_str = "输入为低"
            else:
                pin_in_str = "输入关闭"
            #pull-up/down status
            if (pin_pe):
                if (pin_ps):
                    pin_pull_str = "内部上拉"
                else:
                    pin_pull_str = "内部下拉"
            else:
                pin_pull_str = "无上下拉"
            #interrupt status
            if (i<32):
                pin_oe       = (HPSYS_GPIO.DOER0.value >> i) & 1
                pin_out      = (HPSYS_GPIO.DOR0.value  >> i) & 1
                pin_int_en   = (HPSYS_GPIO.IER0.value  >> i) & 1
                pin_int_type = (HPSYS_GPIO.ITR0.value  >> i) & 1
                pin_int_polh = (HPSYS_GPIO.IPHR0.value >> i) & 1
                pin_int_poll = (HPSYS_GPIO.IPLR0.value >> i) & 1
            else:
                pin_oe       = (HPSYS_GPIO.DOER1.value >> (i-32)) & 1
                pin_out      = (HPSYS_GPIO.DOR1.value  >> (i-32)) & 1
                pin_int_en   = (HPSYS_GPIO.IER1.value  >> (i-32)) & 1
                pin_int_type = (HPSYS_GPIO.ITR1.value  >> (i-32)) & 1
                pin_int_polh = (HPSYS_GPIO.IPHR1.value >> (i-32)) & 1
                pin_int_poll = (HPSYS_GPIO.IPLR1.value >> (i-32)) & 1
            if (pin_int_en):
                if (pin_int_type):
                    if (pin_int_polh and pin_int_poll):
                        pin_int_str = "双边沿触发中断"
                    elif (pin_int_polh):
                        pin_int_str = "上升沿触发中断"
                    elif (pin_int_poll):
                        pin_int_str = "下降沿触发中断"
                    else:
                        pin_int_str = "无法触发中断"
                else:
                    if (pin_int_polh and pin_int_poll):
                        pin_int_str = "所有电平触发中断"
                    elif (pin_int_polh):
                        pin_int_str = "高电平触发中断"
                    elif (pin_int_poll):
                        pin_int_str = "低电平触发中断"
                    else:
                        pin_int_str = "无法触发中断"
            else:
                pin_int_str = "中断关闭"
            #根据不同功能检查不同项目
            if (pin_function == "GPIO"):
                #output status
                if (pin_oe):
                    pin_in_str = "输入屏蔽"
                    if (pin_out):
                        pin_out_str = "输出为高"
                    else:
                        pin_out_str = "输出为低"
                else:
                    pin_out_str = "输出关闭"
                self.log(LogLevel.INFO, f"PA{i:02d}功能为{pin_function},{pin_in_str},{pin_out_str},{pin_pull_str},{pin_int_str}")
            elif (pin_function == "I2C/UART"):
                pin_mapping = self.check_i2c_uart(i)
                if (len(pin_mapping) == 0):
                    self.log(LogLevel.ERROR, f"PA{i:02d}映射到I2C/UART，但是没有指定具体功能",\
                             "请在HPSYS_CFG中将对应功能的PINR指定到PA{i:02d}上")
                    inst_error = 1
                elif (len(pin_mapping) > 1):
                    self.log(LogLevel.ERROR, f"PA{i:02d}映射到如下多个功能上:{pin_mapping}",\
                             "请在HPSYS_CFG中将多余功能的PINR映射到其它IO上，或者不需要映射时设置为0x3f")
                    inst_error = 1
                else:
                    pin_function = pin_mapping[0]
                    self.log(LogLevel.INFO, f"PA{i:02d}功能为{pin_function},{pin_in_str},{pin_pull_str},{pin_int_str}")
            elif (pin_function == "TIM"):
                pin_mapping = self.check_tim(i)
                if (len(pin_mapping) == 0):
                    self.log(LogLevel.ERROR, f"PA{i:02d}映射到TIM，但是没有指定具体功能",\
                             "请在HPSYS_CFG中将对应功能的PINR指定到PA{i:02d}上")
                    inst_error = 1
                elif (len(pin_mapping) > 1):
                    self.log(LogLevel.ERROR, f"PA{i:02d}映射到如下多个功能上:{pin_mapping}",\
                             "请在HPSYS_CFG中将多余功能的PINR映射到其它IO上，或者不需要映射时设置为0x3f")
                    inst_error = 1
                else:
                    pin_function = pin_mapping[0]
                    self.log(LogLevel.INFO, f"PA{i:02d}功能为{pin_function},{pin_in_str},{pin_pull_str},{pin_int_str}")
            else:
                self.log(LogLevel.INFO, f"PA{i:02d}功能为{pin_function},{pin_in_str},{pin_pull_str},{pin_int_str}")
            #check collision between output and pull-up/down resister
            if (self.check_pull(pin_function,pin_pull_str,pin_out_str)):
                inst_error = 1
            #check input enable
            if (self.require_ie(pin_function) and not pin_ie):
                self.log(LogLevel.ERROR, f"{pin_function}功能需要获取输入信号，但是输入使能未开启",\
                         "请在HPSYS_PINMUX中将IE置1")
                inst_error = 1
            #check interrupt configuration
            if (not pin_ie and pin_int_en):
                self.log(LogLevel.ERROR, f"输入关闭，无法触发中断",\
                         "如需触发中断，请在HPSYS_PINMUX中将IE置1")
                inst_error = 1
            if (pin_oe and pin_int_en):
                self.log(LogLevel.ERROR, f"GPIO输出时，无法触发中断",\
                         "如需触发中断，请在HPSYS_GPIO中将对应OE置0")
                inst_error = 1
            if (pin_int_en and not pin_int_type and pin_int_polh and pin_int_poll):
                self.log(LogLevel.WARN, f"所有电平都会触发中断",\
                         "请确认中断需求")
            if (pin_int_en and not pin_int_polh and not pin_int_poll):
                self.log(LogLevel.WARN, f"没有配置中断触发的电平或边沿，无法触发中断",\
                         "请确认中断需求")
            #check power key
            if (i==34 and pin_ie and pin_in):
                self.log(LogLevel.WARN, f"PA34输入为高,持续约10秒会复位芯片",\
                         "请确认PA34连接")
            elif (i==34 and pin_oe and pin_out):
                self.log(LogLevel.ERROR, f"PA34输出为高,持续约10秒会复位芯片",\
                         "PA34应避免作为输出IO")
                inst_error = 1
            
        #输出分析结果
        if (inst_error==1):
            self.log(LogLevel.ERROR, f"{self.periph_name}配置发现错误",\
                     "请检查配置")
        else:
            self.log(LogLevel.INFO, f"{self.periph_name}分析结束，未发现错误")


    #检查I2C与USART的PIN分配是否有冲突
    def check_i2c_uart(self,pin_num):
        HPSYS_CFG = self.read_peripheral("hpsys_cfg")
        pinmux_dict =   {"I2C1_SDA":HPSYS_CFG.I2C1_PINR.SDA_PIN,\
                         "I2C1_SCL":HPSYS_CFG.I2C1_PINR.SCL_PIN,\
                         "I2C2_SDA":HPSYS_CFG.I2C2_PINR.SDA_PIN,\
                         "I2C2_SCL":HPSYS_CFG.I2C2_PINR.SCL_PIN,\
                         "I2C3_SDA":HPSYS_CFG.I2C3_PINR.SDA_PIN,\
                         "I2C3_SCL":HPSYS_CFG.I2C3_PINR.SCL_PIN,\
                         "I2C4_SDA":HPSYS_CFG.I2C4_PINR.SDA_PIN,\
                         "I2C4_SCL":HPSYS_CFG.I2C4_PINR.SCL_PIN,\
                         "USART1_CTS":HPSYS_CFG.USART1_PINR.CTS_PIN,\
                         "USART1_RTS":HPSYS_CFG.USART1_PINR.RTS_PIN,\
                         "USART1_RXD":HPSYS_CFG.USART1_PINR.RXD_PIN,\
                         "USART1_TXD":HPSYS_CFG.USART1_PINR.TXD_PIN,\
                         "USART2_CTS":HPSYS_CFG.USART2_PINR.CTS_PIN,\
                         "USART2_RTS":HPSYS_CFG.USART2_PINR.RTS_PIN,\
                         "USART2_RXD":HPSYS_CFG.USART2_PINR.RXD_PIN,\
                         "USART2_TXD":HPSYS_CFG.USART2_PINR.TXD_PIN,\
                         "USART3_CTS":HPSYS_CFG.USART3_PINR.CTS_PIN,\
                         "USART3_RTS":HPSYS_CFG.USART3_PINR.RTS_PIN,\
                         "USART3_RXD":HPSYS_CFG.USART3_PINR.RXD_PIN,\
                         "USART3_TXD":HPSYS_CFG.USART3_PINR.TXD_PIN \
                         }
        pin_mapping = [key for key, value in pinmux_dict.items() if value == pin_num]
        #print(pin_mapping)
        return pin_mapping


    #检查TIMER的PIN分配是否有冲突
    def check_tim(self,pin_num):
        HPSYS_CFG = self.read_peripheral("hpsys_cfg")
        pinmux_dict =   {"GPTIM1_CH1":HPSYS_CFG.GPTIM1_PINR.CH1_PIN,\
                         "GPTIM1_CH2":HPSYS_CFG.GPTIM1_PINR.CH2_PIN,\
                         "GPTIM1_CH3":HPSYS_CFG.GPTIM1_PINR.CH3_PIN,\
                         "GPTIM1_CH4":HPSYS_CFG.GPTIM1_PINR.CH4_PIN,\
                         "GPTIM1_ETR":HPSYS_CFG.ETR_PINR.ETR1_PIN,\
                         "GPTIM2_CH1":HPSYS_CFG.GPTIM2_PINR.CH1_PIN,\
                         "GPTIM2_CH2":HPSYS_CFG.GPTIM2_PINR.CH2_PIN,\
                         "GPTIM2_CH3":HPSYS_CFG.GPTIM2_PINR.CH3_PIN,\
                         "GPTIM2_CH4":HPSYS_CFG.GPTIM2_PINR.CH4_PIN,\
                         "GPTIM2_ETR":HPSYS_CFG.ETR_PINR.ETR2_PIN,\
                         "LPTIM1_IN" :HPSYS_CFG.LPTIM1_PINR.IN_PIN,\
                         "LPTIM1_OUT":HPSYS_CFG.LPTIM1_PINR.OUT_PIN,\
                         "LPTIM1_ETR":HPSYS_CFG.LPTIM1_PINR.ETR_PIN,\
                         "LPTIM2_IN" :HPSYS_CFG.LPTIM2_PINR.IN_PIN,\
                         "LPTIM2_OUT":HPSYS_CFG.LPTIM2_PINR.OUT_PIN,\
                         "LPTIM2_ETR":HPSYS_CFG.LPTIM2_PINR.ETR_PIN,\
                         "ATIM1_CH1" :HPSYS_CFG.ATIM1_PINR1.CH1_PIN,\
                         "ATIM1_CH2" :HPSYS_CFG.ATIM1_PINR1.CH2_PIN,\
                         "ATIM1_CH3" :HPSYS_CFG.ATIM1_PINR1.CH3_PIN,\
                         "ATIM1_CH4" :HPSYS_CFG.ATIM1_PINR1.CH4_PIN,\
                         "ATIM1_CH1N":HPSYS_CFG.ATIM1_PINR2.CH1N_PIN,\
                         "ATIM1_CH2N":HPSYS_CFG.ATIM1_PINR2.CH2N_PIN,\
                         "ATIM1_CH3N":HPSYS_CFG.ATIM1_PINR2.CH3N_PIN,\
                         "ATIM1_BK"  :HPSYS_CFG.ATIM1_PINR3.BK_PIN,\
                         "ATIM1_BK2" :HPSYS_CFG.ATIM1_PINR3.BK2_PIN,\
                         "ATIM1_ETR" :HPSYS_CFG.ATIM1_PINR3.ETR_PIN,\
                         "BT_ACTIVE"   :HPSYS_CFG.PTA_PINR.BT_ACTIVE,\
                         "BT_COLLISION":HPSYS_CFG.PTA_PINR.BT_COLLISION,\
                         "BT_PRIORITY" :HPSYS_CFG.PTA_PINR.BT_PRIORITY,\
                         "WLAN_ACTIVE" :HPSYS_CFG.PTA_PINR.WLAN_ACTIVE \
                         }
        pin_mapping = [key for key, value in pinmux_dict.items() if value == pin_num]
        #print(pin_mapping)
        return pin_mapping


    #检查上下拉电阻配置是否合理
    def check_pull(self,pin_function,pin_pull_str,pin_out_str):
        inst_error = 0
        if (pin_function == "GPIO"):
            if ((pin_out_str == "输出为高") and (pin_pull_str == "内部下拉")):
                self.log(LogLevel.ERROR, f"IO输出为高但是内部下拉电阻开启，会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
            if ((pin_out_str == "输出为低") and (pin_pull_str == "内部上拉")):
                self.log(LogLevel.ERROR, f"IO输出为低但是内部上拉电阻开启，会产生漏电",\
                         "可改为下拉或关闭上下拉")
                inst_error = 1
        elif (("UART" in pin_function) and ("TXD" in pin_function)):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (("UART" in pin_function) and ("RXD" in pin_function)):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (pin_function.startswith("I2C")):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (pin_function == "LCDC1_SPI_CS"):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (("MPI" in pin_function) and ("CS" in pin_function)):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (("SD" in pin_function) and ("CMD" in pin_function)):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1
        elif (("SPI" in pin_function) and ("CS" in pin_function)):
            if (pin_pull_str == "内部下拉"):
                self.log(LogLevel.ERROR, f"{pin_function}默认为高电平，当内部有下拉电阻时会产生漏电",\
                         "可改为上拉或关闭上下拉")
                inst_error = 1

        return inst_error


    #查询当前IO功能是否需要获取输入信号
    def require_ie(self,pin_function):
        if (pin_function.startswith("I2C")):
            return 1
        elif (("UART" in pin_function) and ("RXD" in pin_function)):
            return 1
        elif (("UART" in pin_function) and ("CTS" in pin_function)):
            return 1
        elif (("SPI" in pin_function) and pin_function.endswith("DI")):
            return 1
        elif (("MPI" in pin_function) and ("DIO" in pin_function)):
            return 1
        elif (("LCDC" in pin_function) and ("DIO" in pin_function)):
            return 1
        elif (("LCDC" in pin_function) and pin_function.endswith("TE")):
            return 1
        elif (("I2S" in pin_function) and pin_function.endswith("SDI")):
            return 1
        elif (("PDM" in pin_function) and pin_function.endswith("DATA")):
            return 1
        elif (("SD" in pin_function) and ("CMD" in pin_function)):
            return 1
        elif (("SD" in pin_function) and ("DIO" in pin_function)):
            return 1
        else:
            return 0

                
register_analyzer("HPSYS_GPIO", HpsysGPIOAnalyzer)

