Exemple #1
0
    def __init__(self, axi4_bus, fft_data_cnt=None):
        if isinstance(axi4_bus, basestring):
            # device path; create axi4lite instance
            self.axi4_bus = AXI4LiteBus(axi4_bus, MIXMagneto002SGRDef.REG_SIZE)
        else:
            self.axi4_bus = axi4_bus

        self.fft_analyzer_axi4_bus = AXI4LiteSubBus(
            self.axi4_bus, MIXMagneto002SGRDef.MIX_FFT_ANAYLZER_IPCORE_ADDR,
            MIXMagneto002SGRDef.MIX_FFT_REG_SIZE)
        self.gpio_axi4_bus = AXI4LiteSubBus(
            self.axi4_bus, MIXMagneto002SGRDef.MIX_GPIO_IPCORE_ADDR,
            MIXMagneto002SGRDef.MIX_GPIO_REG_SIZE)

        self.gpio = MIXGPIOSG(self.gpio_axi4_bus)

        self.i2s_conf_0 = Pin(self.gpio, MIXMagneto002SGRDef.I2S_CONF0_BIT)
        self.i2s_conf_1 = Pin(self.gpio, MIXMagneto002SGRDef.I2S_CONF1_BIT)

        self.cs5361_ovfl = Pin(self.gpio, MIXMagneto002SGRDef.CS5361_OVFL_BIT)
        self.cs5361_rst = Pin(self.gpio, MIXMagneto002SGRDef.CS5361_RST_BIT)
        self.i2s_en = Pin(self.gpio, MIXMagneto002SGRDef.I2S_EN_BIT)
        self.analyzer = MIXFftAnalyzerSG(self.fft_analyzer_axi4_bus,
                                         fft_data_cnt)

        self.reset()
Exemple #2
0
def create_dazzler_dbg(i2s_rx_en_pin, adc_rst_pin, gpio_dev,
                       i2s_tx_en_pin, dac_rst_pin,
                       i2c_dev, mix_aut1_dev):

    dazzler_dbg = DazzlerDebuger()

    if utility.is_pl_device(i2c_dev):
        axi4_bus = AXI4LiteBus(i2c_dev, 256)
        i2c_bus = MIXI2CSG(axi4_bus)
    else:
        i2c_bus = I2C(i2c_dev)

    axi4 = AXI4LiteBus(mix_aut1_dev, 0x8000)
    mix_aut1 = MIXAUT1SGR(axi4)

    if gpio_dev != "":
        axi4 = AXI4LiteBus(gpio_dev, 256)
        gpio = MIXGPIOSG(axi4)
        analyzer_rst = Pin(gpio, adc_rst_pin)
        analyzer_en = Pin(gpio, i2s_rx_en_pin)
        signal_source_rst = Pin(gpio, dac_rst_pin)
        signal_source_en = Pin(gpio, i2s_tx_en_pin)
        dazzler_dbg.audio = Audio001004(i2c=i2c_bus, adc_rst_pin=analyzer_rst,
                                        i2s_rx_en_pin=analyzer_en,
                                        dac_rst_pin=signal_source_rst,
                                        i2s_tx_en_pin=signal_source_en,
                                        ipcore=mix_aut1)
    else:
        dazzler_dbg.audio = Audio001004(i2c=i2c_bus, ipcore=mix_aut1)

    return dazzler_dbg
    def __init__(self,
                 i2c,
                 ipcore,
                 dma=None,
                 left_ch_id=None,
                 right_ch_id=None,
                 dma_mem_size=1):
        super(Audio005002, self).__init__(i2c, ipcore)

        self.ram_signal = self.ipcore.ram_signal
        self.audio_cache = self.ipcore.audio_cache
        self.ram_out_pin = Pin(self.ipcore.gpio, Audio005002Def.RAM_OUT_PIN)

        self.adc_sample_rate = Audio005002Def.DEF_SAMPLING_RATE
        self.dac_sample_rate = Audio005002Def.AUDIO_SAMPLING_RATE
        self.vref = [
            Audio005002Def.ANALYZER_2V_VOLT, Audio005002Def.ANALYZER_2V_VOLT
        ]
        self.input_enable = [False, False]
        self.output_enable = False
        self.model = Audio005002Def.AUDIO005002_CONFIG

        self.dma = dma
        if self.dma is not None:
            self.left_ch_id = left_ch_id
            self.right_ch_id = right_ch_id
            self.dma_mem_size = dma_mem_size
            if self.left_ch_id is None or self.right_ch_id is None or self.dma_mem_size is None:
                raise Audio005002Exception("dma parameter error")
Exemple #4
0
    def __init__(self, i2c, ipcore, range_table=starlordii_range_table):

        self.eeprom = CAT24C32(Audio005Def.EEPROM_I2C_ADDR, i2c)
        self.nct75 = NCT75(Audio005Def.TEMP_I2C_ADDR, i2c)
        self.pca9536 = PCA9536(Audio005Def.PCA9536_DEV_ADDR, i2c)

        if isinstance(ipcore, basestring):
            ipcore = MIXAudio005SGR(ipcore)

        self.ipcore = ipcore
        self.analyzer = self.ipcore.analyzer
        self.signal_source = self.ipcore.signal_source
        self.adc_rst_pin = Pin(self.ipcore.gpio, Audio005Def.ADC_RESET_PIN)
        self.i2s_rx_en_pin = Pin(self.ipcore.gpio, Audio005Def.I2S_RX_EN_PIN)
        self.dac_rst_pin = Pin(self.ipcore.gpio, Audio005Def.DAC_RESET_PIN)
        self.i2s_tx_en_pin = Pin(self.ipcore.gpio, Audio005Def.I2S_TX_EN_PIN)
        self.i2s_ch_select = [
            Pin(self.ipcore.gpio, Audio005Def.I2S_CH_SELECT_2),
            Pin(self.ipcore.gpio, Audio005Def.I2S_CH_SELECT_3)
        ]

        super(Audio005Base, self).__init__(self.eeprom,
                                           self.nct75,
                                           range_table=range_table)
        self.is_enable_upload = False
Exemple #5
0
def create_wolverine_dbg(ad7175_bus_name, vref, i2c_bus0_name, i2c_bus1_name,
                         i2c_dev_addr1, range_sel_bit, meter_sel_bit,
                         ip_dev_name):

    if ad7175_bus_name == '':
        ad7175 = None
    else:
        axi4_bus = AXI4LiteBus(ad7175_bus_name, 8192)
        ad7175 = MIXAd7175SG(axi4_bus, vref)
    if i2c_bus0_name == '':
        i2c_bus0 = None
    else:
        if utility.is_pl_device(i2c_bus0_name):
            axi4_bus = AXI4LiteBus(i2c_bus0_name, 256)
            i2c_bus0 = MIXI2CSG(axi4_bus)
        else:
            i2c_bus0 = I2C(i2c_bus0_name)

    if i2c_bus1_name == '':
        cat9555 = None
    else:
        if utility.is_pl_device(i2c_bus1_name):
            axi4_bus = AXI4LiteBus(i2c_bus1_name, 256)
            i2c_bus1 = MIXI2CSG(axi4_bus)
        else:
            i2c_bus1 = I2C(i2c_bus1_name)
        cat9555 = CAT9555(i2c_dev_addr1, i2c_bus1)

    if ip_dev_name == '':
        ipcore = None
    else:
        axi4_bus = AXI4LiteBus(ip_dev_name, 0x8000)
        ipcore = MIXDAQT1SGR(axi4_bus,
                             ad717x_chip='AD7175',
                             use_spi=False,
                             use_gpio=True)

    if range_sel_bit == '':
        range_sel_bit = None
    else:
        range_sel_bit = int(range_sel_bit)

    if meter_sel_bit == '':
        meter_sel_bit = None
    else:
        meter_sel_bit = int(meter_sel_bit)

    wolverine_dbg = WolverineDebugger(
        Wolverine(i2c_bus0, ad7175, Pin(cat9555, range_sel_bit),
                  Pin(cat9555, meter_sel_bit), ipcore))
    return wolverine_dbg
Exemple #6
0
    def __init__(self, axi4_bus, fft_data_cnt=None):
        if isinstance(axi4_bus, basestring):
            # device path; create axi4lite instance
            self.axi4_bus = AXI4LiteBus(axi4_bus, MIXAUT1SGRDef.REG_SIZE)
        else:
            self.axi4_bus = axi4_bus

        if self.axi4_bus is None:
            self.analyzer = MIXFftAnalyzerSGEmulator(
                'mix_fftanalyzer_sg_emulator')
            self.signal_source = MIXSignalSourceSGEmulator(
                "mix_signalsource_sg_emulator")
            self.gpio = MIXGPIOSGEmulator("mix_gpio_sg_emulator", 256)
        else:
            self.fft_analyzer_axi4_bus = AXI4LiteSubBus(
                self.axi4_bus, MIXAUT1SGRDef.MIX_FFT_ANAYLZER_IPCORE_ADDR,
                MIXAUT1SGRDef.MIX_FFT_REG_SIZE)
            self.analyzer = MIXFftAnalyzerSG(self.fft_analyzer_axi4_bus,
                                             fft_data_cnt)

            self.signal_source_axi4_bus = AXI4LiteSubBus(
                self.axi4_bus, MIXAUT1SGRDef.MIX_SIGNAL_SOURCE_IPCORE_ADDR,
                MIXAUT1SGRDef.MIX_SIGNAL_SOURCE_REG_SIZE)
            self.signal_source = MIXSignalSourceSG(self.signal_source_axi4_bus)

            self.gpio_axi4_bus = AXI4LiteSubBus(
                self.axi4_bus, MIXAUT1SGRDef.MIX_GPIO_IPCORE_ADDR,
                MIXAUT1SGRDef.MIX_GPIO_REG_SIZE)
            self.gpio = MIXGPIOSG(self.gpio_axi4_bus)
        self.adc_rst_pin = Pin(self.gpio, MIXAUT1SGRDef.ADC_RESET_PIN)
        self.i2s_rx_en_pin = Pin(self.gpio, MIXAUT1SGRDef.I2S_RX_EN_PIN)
        self.dac_rst_pin = Pin(self.gpio, MIXAUT1SGRDef.DAC_RESET_PIN)
        self.i2s_tx_en_pin = Pin(self.gpio, MIXAUT1SGRDef.I2S_TX_EN_PIN)
Exemple #7
0
    def __init__(self, firmware_path, pl_uart_drv_ko_file, i2c, pull_up_pin,
                 pull_down_pin, tx_en_pin, removal_det_pin, connect_det_pin,
                 a0_pin, a1_pin, a2_pin, elaod_en_pin, eeprom_devaddr, gpio):
        self.path = firmware_path
        self.process = None
        self.pl_uart_drv_ko_file = pl_uart_drv_ko_file
        if (firmware_path == '' and pl_uart_drv_ko_file == '' and i2c is None
                and pull_up_pin is None and pull_down_pin is None
                and tx_en_pin is None and removal_det_pin is None
                and connect_det_pin is None):
            self.eeprom = EepromEmulator('eeprom_emulator')
            self.pull_up_pin = GPIOEmulator('pull_up_pin')
            self.pull_down_pin = GPIOEmulator('pull_down_pin')
            self.tx_en_pin = GPIOEmulator('tx_en_pin')
            self.removal_det_pin = GPIOEmulator('removal_det_pin')
            self.connect_det_pin = GPIOEmulator('connect_det_pin')
        elif (firmware_path != '' and pl_uart_drv_ko_file != ''
              and i2c is not None and pull_up_pin is not None
              and pull_down_pin is not None and tx_en_pin is not None
              and removal_det_pin is not None and connect_det_pin is not None):
            self.eeprom = CAT24C02(eeprom_devaddr, i2c)
            self.pull_up_pin = pull_up_pin
            self.pull_down_pin = pull_down_pin
            self.tx_en_pin = tx_en_pin
            self.removal_det_pin = removal_det_pin
            self.connect_det_pin = connect_det_pin
        else:
            raise DarkBeastException(
                '__init__ error! Please check the parameters!')
        self.gpio = gpio
        if (a0_pin is None and a1_pin is None and a2_pin is None
                and elaod_en_pin is None):
            self.a0_pin = Pin(None, DarkBeastDef.A0_PIN_ID)
            self.a1_pin = Pin(None, DarkBeastDef.A1_PIN_ID)
            self.a2_pin = Pin(None, DarkBeastDef.A2_PIN_ID)
            self.elaod_en_pin = Pin(None, DarkBeastDef.ELAOD_EN_PIN_ID)
        elif (a0_pin is not None and a1_pin is not None and a2_pin is not None
              and elaod_en_pin is not None):
            self.a0_pin = a0_pin
            self.a1_pin = a1_pin
            self.a2_pin = a2_pin
            self.elaod_en_pin = elaod_en_pin
        else:
            raise DarkBeastException(
                '__init__ error! Please check the parameters!')

        super(DarkBeastBase, self).__init__(self.eeprom, None)
        self.pin_def = {
            'PULL_UP': self.pull_up_pin,
            'PULL_DOWN': self.pull_down_pin,
            'TX_EN': self.tx_en_pin,
            'REMOVAL_DETECTION': self.removal_det_pin,
            'CONNECT_DETECTION': self.connect_det_pin,
            'A0': self.a0_pin,
            'A1': self.a1_pin,
            'A2': self.a2_pin,
            'ELAOD_EN': self.elaod_en_pin
        }
Exemple #8
0
 def __init__(self, i2c, signal_source, range_ctrl_pin, ipcore, eeprom_dev_addr, sensor_dev_addr):
     if not i2c and not signal_source and not range_ctrl_pin and not ipcore:
         self.signal_source = MIXSignalSourceSGEmulator('mix_signalsource_sg_emulator')
         self.range_ctrl_pin = GPIOEmulator('gpio_emulator')
     elif i2c and signal_source and range_ctrl_pin and not ipcore:
         if isinstance(signal_source, basestring):
             axi4_bus = AXI4LiteBus(signal_source, IcemanDef.REG_SIZE)
             self.signal_source = MIXSignalSourceSG(axi4_bus)
         else:
             self.signal_source = signal_source
         self.range_ctrl_pin = range_ctrl_pin
     elif i2c and not signal_source and ipcore:
         if isinstance(ipcore, basestring):
             axi4_bus = AXI4LiteBus(ipcore, IcemanDef.MIX_SGT1_REG_SIZE)
             use_gpio = False if range_ctrl_pin else True
             self.ipcore = MIXSGT1SGR(axi4_bus, use_gpio)
         else:
             self.ipcore = ipcore
         self.signal_source = self.ipcore.signal_source
         self.range_ctrl_pin = range_ctrl_pin or Pin(self.ipcore.gpio, IcemanDef.RANGE_CTRL_PIN)
     else:
         raise IcemanException("Please check init parameters.")
     if i2c:
         eeprom = CAT24C32(eeprom_dev_addr, i2c)
         nct75 = NCT75(sensor_dev_addr, i2c)
     else:
         eeprom = None
         nct75 = None
     super(IcemanBase, self).__init__(eeprom, nct75, cal_table=iceman_calibration, range_table=iceman_range_table)
Exemple #9
0
def create_ad9102_dbg(spi_bus_name,
                      cs_ctrl=None,
                      cs_chip=None,
                      cs_addr=None,
                      cs_i2c=None):
    ad9102_dbg = AD9102Debuger()
    if spi_bus_name == '':
        spi_bus = None
    else:
        axi4_bus = AXI4LiteBus(spi_bus_name, PLSPIDef.REG_SIZE)
        spi_bus = MIXQSPISG(axi4_bus)
        spi_bus.set_mode('MODE3')
        spi_bus.set_speed(800000)

    if cs_ctrl is not None:
        cs_chip = str(cs_chip)
        if '0x' in cs_addr:
            cs_addr = int(cs_addr, 16)
        else:
            cs_addr = int(cs_addr)
        cs_i2c = str(cs_i2c)
        cs_i2c = I2C(cs_i2c)
        exec('from ..ic.{} import {}'.format(cs_chip.lower(), cs_chip.upper()))
        cs_chip = eval(cs_chip.upper())(cs_addr, cs_i2c)
        cs = Pin(cs_chip, int(cs_ctrl))
    else:
        cs = None
    ad9102_dbg.ad9102 = AD9102(spi_bus, cs=cs)
    return ad9102_dbg
Exemple #10
0
def create_dazzler_dbg(fftrt_dev, i2s_rx_en_pin, adc_rst_pin, gpio_dev,
                       signal_source_dev, i2s_tx_en_pin, dac_rst_pin, i2c_dev,
                       mix_aut1_dev):

    dazzler_dbg = DazzlerDebuger()

    if i2c_dev != '':
        if utility.is_pl_device(i2c_dev):
            axi4_bus = AXI4LiteBus(i2c_dev, 256)
            i2c_bus = MIXI2CSG(axi4_bus)
        else:
            i2c_bus = I2C(i2c_dev)
    else:
        i2c_bus = None

    if mix_aut1_dev != '':
        axi4 = AXI4LiteBus(mix_aut1_dev, 0x8000)
        mix_aut1 = MIXAUT1SGR(axi4)
        dazzler_dbg.audio = Dazzler(i2c_bus, ip=mix_aut1)
    else:
        axi4 = AXI4LiteBus(fftrt_dev, 256)
        analyzer = MIXFftAnalyzerSG(axi4)

        axi4 = AXI4LiteBus(signal_source_dev, 256)
        signal_source = MIXSignalSourceSG(axi4)

        axi4 = AXI4LiteBus(gpio_dev, 256)
        gpio = MIXGPIOSG(axi4)
        analyzer_rst = Pin(gpio, adc_rst_pin)
        analyzer_en = Pin(gpio, i2s_rx_en_pin)
        signal_source_rst = Pin(gpio, dac_rst_pin)
        signal_source_en = Pin(gpio, i2s_tx_en_pin)
        dazzler_dbg.audio = Dazzler(i2c_bus,
                                    analyzer=analyzer,
                                    signal_source=signal_source,
                                    adc_rst_pin=analyzer_rst,
                                    i2s_rx_en_pin=analyzer_en,
                                    dac_rst_pin=signal_source_rst,
                                    i2s_tx_en_pin=signal_source_en,
                                    ip=mix_aut1)

    return dazzler_dbg
Exemple #11
0
def create_dbg(file, uart, i2c_bus_name, plgpio, pull_up_pin_num,
               pull_down_pin_num, tx_en_pin_num, removal_det_pin_num,
               connect_det_pin_num, a0_pin_id, a1_pin_id, a2_pin_id,
               elaod_en_pin_id):
    dbg = DarkBeastDebuger()

    firmware_path = file
    pl_uart_drv_ko_file = uart

    if i2c_bus_name == '':
        i2c_bus = None
    else:
        if utility.is_pl_device(i2c_bus_name):
            axi4_bus = AXI4LiteBus(i2c_bus_name, 256)
            i2c_bus = MIXI2CSG(axi4_bus)
        else:
            i2c_bus = I2C(i2c_bus_name)

    if plgpio == '':
        gpio = None
    else:
        axi4_bus = AXI4LiteBus(plgpio, 256)
        gpio = MIXGPIOSG(axi4_bus)

    pull_up_pin = GPIO(int(pull_up_pin_num))
    pull_down_pin = GPIO(int(pull_down_pin_num))
    tx_en_pin = GPIO(int(tx_en_pin_num))
    removal_det_pin = GPIO(int(removal_det_pin_num))
    connect_det_pin = GPIO(int(connect_det_pin_num))

    cat9555 = CAT9555(0x20, i2c_bus)
    a0_pin = Pin(cat9555, a0_pin_id)
    a1_pin = Pin(cat9555, a1_pin_id)
    a2_pin = Pin(cat9555, a2_pin_id)
    elaod_en_pin = Pin(cat9555, elaod_en_pin_id)
    dbg.darkbeast = DarkBeast(firmware_path, pl_uart_drv_ko_file, i2c_bus,
                              gpio, pull_up_pin, pull_down_pin, tx_en_pin,
                              removal_det_pin, connect_det_pin, a0_pin, a1_pin,
                              a2_pin, elaod_en_pin)
    return dbg
def create_negasonic_dbg(fftrt_dev, i2s_rx_en_pin, adc_rst_pin, gpio_dev,
                         signal_source_dev, i2s_tx_en_pin, dac_rst_pin,
                         i2c_dev, mix_aut1_dev):

    audio002002_dbg = NegasonicDebuger()

    if utility.is_pl_device(i2c_dev):
        axi4_bus = AXI4LiteBus(i2c_dev, 256)
        i2c_bus = MIXI2CSG(axi4_bus)
    else:
        i2c_bus = I2C(i2c_dev)

    if mix_aut1_dev != '':
        axi4 = AXI4LiteBus(mix_aut1_dev, 0x8000)
        mix_aut1 = MIXAUT1(axi4)
        audio002002_dbg.audio = Negasonic(i2c_bus, ip=mix_aut1)
    else:
        axi4 = AXI4LiteBus(fftrt_dev, 256)
        analyzer = MIXFftAnalyzerSG(axi4)

        axi4 = AXI4LiteBus(signal_source_dev, 256)
        signal_source = MIXSignalSourceSG(axi4)

        axi4 = AXI4LiteBus(gpio_dev, 256)
        gpio = MIXGPIOSG(axi4)
        analyzer_rst = Pin(gpio, adc_rst_pin)
        analyzer_en = Pin(gpio, i2s_rx_en_pin)
        signal_source_rst = Pin(gpio, dac_rst_pin)
        signal_source_en = Pin(gpio, i2s_tx_en_pin)
        audio002002_dbg.audio = Negasonic(i2c_bus,
                                          analyzer=analyzer,
                                          signal_sourc=signal_source,
                                          analyzer_rst=analyzer_rst,
                                          analyzer_en=analyzer_en,
                                          signal_source_rst=signal_source_rst,
                                          signal_source_en=signal_source_en)

    return audio002002_dbg
Exemple #13
0
def create_se2300_dbg(gpio_device, i2c_bus_1, i2c_bus_2, ps_ipcore,
                      trigger_ipcore):
    se2300_dbg = Se2300ps01pcbDebuger()

    if gpio_device == '':
        gpio = None
    else:
        axi4_bus = AXI4LiteBus(gpio_device, 256)
        gpio = MIXGPIOSG(axi4_bus)
    ads5231_oea = Pin(gpio, 1)
    data_upload = Pin(gpio, 4)
    if i2c_bus_1 == '':
        iic_1 = None
    else:
        axi4_bus = AXI4LiteBus(i2c_bus_1, 256)
        iic_1 = MIXI2CSG(axi4_bus)

    if i2c_bus_2 == '':
        iic_2 = None
    else:
        axi4_bus = AXI4LiteBus(i2c_bus_2, 256)
        iic_2 = MIXI2CSG(axi4_bus)

    if ps_ipcore == '':
        power_sequency = None
    else:
        axi4_bus = AXI4LiteBus(ps_ipcore, 1024)
        power_sequency = MIXPowerSequenceSG(axi4_bus)

    if trigger_ipcore == '':
        trigger_core = None
    else:
        axi4_bus = AXI4LiteBus(trigger_ipcore, 1024)
        trigger_core = MIXPowerSequenceSG(axi4_bus)

    se2300_dbg.se2300 = SE2300PS01PCB(ads5231_oea, data_upload, iic_1, iic_2,
                                      power_sequency, trigger_core)
    return se2300_dbg
    def __init__(self,
                 i2c,
                 adc_rst_pin=None,
                 i2s_rx_en_pin=None,
                 dac_rst_pin=None,
                 i2s_tx_en_pin=None,
                 sample_rate=192000,
                 ipcore=None):
        assert sample_rate > 0 and sample_rate <= DazzlerDef.MAX_SAMPLING_RATE

        self.eeprom = CAT24C32(DazzlerDef.EEPROM_I2C_ADDR, i2c)
        self.nct75 = NCT75(DazzlerDef.SENSOR_I2C_ADDR, i2c)

        super(DazzlerBase, self).__init__(self.eeprom,
                                          self.nct75,
                                          range_table=dazzler_range_table)

        if ipcore:
            if isinstance(ipcore, basestring):
                axi4 = AXI4LiteBus(ipcore, DazzlerDef.MIX_AUT1_REG_SIZE)
                self.ip = MIXAUT1SGR(axi4)
            else:
                self.ip = ipcore
            self.analyzer = self.ip.analyzer
            self.signal_source = self.ip.signal_source
            self.adc_rst_pin = adc_rst_pin or Pin(self.ip.gpio,
                                                  DazzlerDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = i2s_rx_en_pin or Pin(self.ip.gpio,
                                                      DazzlerDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = dac_rst_pin or Pin(self.ip.gpio,
                                                  DazzlerDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = i2s_tx_en_pin or Pin(self.ip.gpio,
                                                      DazzlerDef.I2S_TX_EN_PIN)
        else:
            raise DazzlerException("parameter 'ipcore' can not be None")

        self.sample_rate = sample_rate
    def __init__(self, i2c, ad7175=None, ipcore=None):

        self.eeprom = CAT24C32(Scope002006Def.EEPROM_DEV_ADDR, i2c)
        self.sensor = NCT75(Scope002006Def.SENSOR_DEV_ADDR, i2c)

        if ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore,
                                       Scope002006Def.MIX_DAQT1_REG_SIZE)
                ipcore = MIXDAQT1SGR(
                    axi4_bus,
                    'AD7175',
                    ad717x_mvref=Scope002006Def.AD7175_MVREF,
                    code_polar=Scope002006Def.AD7175_CODE_POLAR,
                    reference=Scope002006Def.AD7175_REFERENCE_SOURCE,
                    buffer_flag=Scope002006Def.AD7175_BUFFER_FLAG,
                    clock=Scope002006Def.AD7175_CLOCK,
                    use_spi=False,
                    use_gpio=True)
            ipcore.ad717x.config = {"ch0": {"P": "AIN0", "N": "AIN1"}}
            self.ad7175 = ipcore.ad717x
            self.gpio = ipcore.gpio
            self.tag_pins = [
                Pin(self.gpio, Scope002006Def.TAG_BASE_PIN + x,
                    Scope002006Def.GPIO_OUTPUT_DIR) for x in xrange(4)
            ]
        elif ad7175:
            if isinstance(ad7175, basestring):
                axi4_bus = AXI4LiteBus(ad7175, Scope002006Def.AD7175_REG_SIZE)
                ad7175 = MIXAd7175SG(
                    axi4_bus,
                    mvref=Scope002006Def.AD7175_MVREF,
                    code_polar=Scope002006Def.AD7175_CODE_POLAR,
                    reference=Scope002006Def.AD7175_REFERENCE_SOURCE,
                    buffer_flag=Scope002006Def.AD7175_BUFFER_FLAG,
                    clock=Scope002006Def.AD7175_CLOCK)

            ad7175.config = {"ch0": {"P": "AIN0", "N": "AIN1"}}
            self.ad7175 = ad7175
        else:
            raise Scope002006Exception('Use one of aggregated IP or AD717X')

        super(Scope002006, self).__init__(self.eeprom,
                                          self.sensor,
                                          range_table=scope002006_range_table)
Exemple #16
0
    def __init__(self, i2c, ad7175=None, range_ctrl_pin=None,
                 meter_ctrl_pin=None, ipcore=None):

        if ad7175 and range_ctrl_pin and meter_ctrl_pin and not ipcore:
            if isinstance(ad7175, basestring):
                axi4 = AXI4LiteBus(ad7175, WolverineDef.PLAD7175_REG_SIZE)
                self.ad7175 = MIXAd7175SG(axi4, mvref=WolverineDef.MVREF, code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK)
            else:
                self.ad7175 = ad7175
            self.range_ctrl_pin = range_ctrl_pin
            self.meter_ctrl_pin = meter_ctrl_pin
        elif not ad7175 and not range_ctrl_pin and not meter_ctrl_pin and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus, 'AD7175', ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR, clock=WolverineDef.CLOCK, use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            gpio = self.ipcore.gpio
            self.range_ctrl_pin = Pin(gpio, WolverineDef.RANGE_SEL_BIT)
            self.meter_ctrl_pin = Pin(gpio, WolverineDef.METER_SEL_BIT)
            self.tag_pins = [
                Pin(gpio, WolverineDef.TAG_BASE_PIN + x,
                    WolverineDef.GPIO_OUTPUT_DIR) for x in range(4)
            ]
        elif not ad7175 and range_ctrl_pin and meter_ctrl_pin and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus, 'AD7175', ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR, clock=WolverineDef.CLOCK, use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            self.range_ctrl_pin = range_ctrl_pin
            self.meter_ctrl_pin = meter_ctrl_pin
            gpio = self.ipcore.gpio
            self.tag_pins = [
                Pin(gpio, WolverineDef.TAG_BASE_PIN + x,
                    WolverineDef.GPIO_OUTPUT_DIR) for x in range(4)
            ]
        else:
            raise WolverineException("Invalid parameter, please check")

        eeprom = CAT24C32(WolverineDef.EEPROM_DEV_ADDR, i2c)
        nct75 = NCT75(WolverineDef.NCT75_DEV_ADDR, i2c)
        super(Wolverine, self).__init__(eeprom, nct75, range_table=wolverine_range_table)

        self.channel_path = {'range_sel_bit': self.range_ctrl_pin, 'meter_sel_bit': self.meter_ctrl_pin}
        self.measure_path = dict()
        self.measure_path['range'] = WolverineDef.VOLT_5V
Exemple #17
0
def create_elektra_dbg(i2c_name, spi_name, ad760x_name, gpio_id, volt_ch_1,
                       volt_ch_2, curr_ch_1, curr_ch_2):
    scope_dbg = ElektraDebuger()
    if i2c_name == '':
        i2c_bus = None
    else:
        if utility.is_pl_device(i2c_name):
            axi4_bus = AXI4LiteBus(i2c_name, 256)
            i2c_bus = MIXI2CSG(axi4_bus)
        else:
            i2c_bus = I2C(i2c_name)

    if spi_name == '':
        spi_bus = None
    else:
        axi4_bus = AXI4LiteBus(spi_name, 8192)
        spi_bus = MIXQSPISG(axi4_bus)

    if ad760x_name == '':
        ad7608_ip = None
    else:
        axi4 = AXI4LiteBus(ad760x_name, 8192)
        ad7608_ip = MIXAd7608SG(axi4)

    if gpio_id == '':
        gpio_bus = None
    else:
        io = GPIO(gpio_id, "output")
        gpio_bus = Pin(io, gpio_id, "output")

    volt_1 = int(volt_ch_1)
    volt_2 = int(volt_ch_2)
    curr_1 = int(curr_ch_1)
    curr_2 = int(curr_ch_2)
    scope_dbg.elektra = Elektra(i2c=i2c_bus,
                                spi=spi_bus,
                                ad7608=ad7608_ip,
                                gpio=gpio_bus,
                                volt_ch1=volt_1,
                                volt_ch2=volt_2,
                                curr_ch1=curr_1,
                                curr_ch2=curr_2)
    return scope_dbg
def create_elektra_dbg(i2c_name, spi_name, ad717x_name, gpio_id, ipcore_name):
    scope_dbg = ElektraDebuger()
    if i2c_name == '':
        i2c_bus = None
    else:
        if utility.is_pl_device(i2c_name):
            axi4_bus = AXI4LiteBus(i2c_name, 256)
            i2c_bus = MIXI2CSG(axi4_bus)
        else:
            i2c_bus = I2C(i2c_name)

    if spi_name == '':
        spi_bus = None
    else:
        axi4_bus = AXI4LiteBus(spi_name, 8192)
        spi_bus = MIXQSPISG(axi4_bus)

    ipcore = None
    ad7175 = None
    vref = 5000
    if ipcore_name != '':
        axi4_bus = AXI4LiteBus(ipcore_name, 9548)
        ipcore = MIXDAQT1SGR(axi4_bus,
                             ad717x_mvref=vref,
                             use_spi=True,
                             use_gpio=False)
    elif ad717x_name != '':
        axi4_bus = AXI4LiteBus(ad717x_name, 256)
        ad7175 = MIXAd7175SG(axi4_bus, vref)

    if gpio_id == '':
        gpio_bus = None
    else:
        io = GPIO(gpio_id, "output")
        gpio_bus = Pin(io, gpio_id, "output")

    scope_dbg.elektra = EL004002A(i2c=i2c_bus,
                                  spi=spi_bus,
                                  ad7175=ad7175,
                                  gpio=gpio_bus,
                                  ipcore=ipcore)
    return scope_dbg
Exemple #19
0
    def __init__(self, i2c, ipcore):

        self.eeprom = CAT24C32(WolverineiiDef.EEPROM_DEV_ADDR, i2c)
        self.sensor = NCT75(WolverineiiDef.SENSOR_DEV_ADDR, i2c)
        self.pca9536 = PCA9536(WolverineiiDef.IO_EXP_DEV_ADDR, i2c)

        if isinstance(ipcore, basestring):
            axi4_bus = AXI4LiteBus(ipcore, WolverineiiDef.MIXDAQT1_REG_SIZE)
            ipcore = MIXDAQT1SGR(axi4_bus,
                                 'AD7175',
                                 ad717x_mvref=WolverineiiDef.AD7175_MVREF,
                                 code_polar=WolverineiiDef.AD7175_CODE_POLAR,
                                 reference=WolverineiiDef.AD7175_REFERENCE,
                                 clock=WolverineiiDef.AD7175_CLOCK,
                                 use_gpio=True)

        self.ipcore = ipcore
        self.ad7175 = self.ipcore.ad717x
        self.ad7175.config = {
            'ch0': {
                'P': 'AIN0',
                'N': 'AIN1'
            },
            'ch1': {
                'P': 'AIN2',
                'N': 'AIN3'
            }
        }

        self.measure_path = dict()

        self.continuous_sample_mode = None

        self.gpio = ipcore.gpio
        self.tag_pins = [
            Pin(self.gpio, WolverineiiDef.TAG_BASE_PIN + x,
                WolverineiiDef.GPIO_OUTPUT_DIR) for x in range(4)
        ]

        super(WolverineII, self).__init__(self.eeprom,
                                          self.sensor,
                                          range_table=wolverineii_range_table)
Exemple #20
0
def create_iceman_dbg(ip_name, signal_source_name, io_name, pin, i2c_name):
    iceman_dbg = None
    if utility.is_pl_device(i2c_name):
        axi4_bus = AXI4LiteBus(i2c_name, 256)
        i2c = MIXI2CSG(axi4_bus)
    else:
        i2c = I2C(i2c_name)

    if ip_name == '':
        axi4_bus = AXI4LiteBus(signal_source_name, 256)
        signal_source = MIXSignalSourceSG(axi4_bus)
        axi4_bus = AXI4LiteBus(io_name, 256)
        pl_gpio = MIXGPIOSG(axi4_bus)
        iceman_dbg = IcemanDebugger()
        iceman_dbg.iceman = Iceman(i2c, signal_source, Pin(pl_gpio, pin))
    else:
        axi4_bus = AXI4LiteBus(ip_name, 0x8000)
        mix_sgt1 = MIXSGT1SGR(axi4_bus)
        iceman_dbg = IcemanDebugger()
        iceman_dbg.iceman = Iceman(i2c, ipcore=mix_sgt1)
    return iceman_dbg
Exemple #21
0
    def __init__(self, i2c, ad7177=None, ipcore=None):
        if ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, CloakDef.MIX_DAQT1_REG_SIZE)
                ipcore = MIXDAQT1SGR(
                    axi4_bus,
                    'AD7177',
                    ad717x_mvref=CloakDef.AD7177_MVREF,
                    code_polar=CloakDef.AD7177_CODE_POLAR,
                    reference=CloakDef.AD7177_REFERENCE_SOURCE,
                    buffer_flag=CloakDef.AD7177_BUFFER_FLAG,
                    clock=CloakDef.AD7177_CLOCK,
                    use_spi=False,
                    use_gpio=True)
            self.gpio = ipcore.gpio
            self.tag_pins = [
                Pin(self.gpio, CloakDef.TAG_BASE_PIN + x,
                    CloakDef.GPIO_OUTPUT_DIR) for x in xrange(4)
            ]
        elif ad7177:
            if isinstance(ad7177, basestring):
                axi4_bus = AXI4LiteBus(ad7177, CloakDef.AD7177_REG_SIZE)
                ad7177 = MIXAd7177SG(
                    axi4_bus,
                    mvref=CloakDef.AD7177_MVREF,
                    code_polar=CloakDef.AD7177_CODE_POLAR,
                    reference=CloakDef.AD7177_REFERENCE_SOURCE,
                    buffer_flag=CloakDef.AD7177_BUFFER_FLAG,
                    clock=CloakDef.AD7177_CLOCK)
        else:
            ad7177 = MIXAd7177SGEmulator('mix_ad7177_sg_emulator', 2500)

        super(Cloak,
              self).__init__(i2c, ad7177, ipcore, CloakDef.EEPROM_DEV_ADDR,
                             CloakDef.SENSOR_DEV_ADDR, cloak_calibration_info,
                             cloak_range_table)
Exemple #22
0
    def __init__(self, spi_bus=None, pdwn_ctrl=None, oeb_ctrl=None, cs_ctrl=None, use_cs=True):
        if(spi_bus is None and pdwn_ctrl is None and oeb_ctrl is None):
            self.spi_bus = MIXQSPISGEmulator("ad9628_emulator", 256)
            self.pdwn = Pin(None, 6)
            self.oeb = Pin(None, 7)
        elif(spi_bus is not None and pdwn_ctrl is not None and oeb_ctrl is not None):
            self.spi_bus = spi_bus
            self.pdwn = pdwn_ctrl
            self.oeb = oeb_ctrl
        else:
            raise AD9628RException('__init__ error! Please check the parameters')

        self.use_cs = use_cs
        if(self.use_cs is True and cs_ctrl is not None):
            self.cs = cs_ctrl
        elif(self.use_cs is False and cs_ctrl is None):
            self.cs = Pin(None, 12)
        else:
            raise AD9628RException('cs use error! Please check the parameters')
Exemple #23
0
    def __init__(self,
                 ipcore=None,
                 signal_meter_0=None,
                 signal_meter_1=None,
                 spi=None,
                 i2c=None,
                 eeprom_dev_addr=MagikDef.EEPROM_DEV_ADDR,
                 sensor_dev_addr=MagikDef.SENSOR_DEV_ADDR):
        if ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, MagikDef.MIX_DAQT2_REG_SIZE)
                self.mix_daqt2 = MIXDAQT2SGR(axi4_bus,
                                             use_signal_meter1=True,
                                             use_spi=True,
                                             use_gpio=False)
                self.signal_meter0 = self.mix_daqt2.signal_meter0
                self.signal_meter1 = self.mix_daqt2.signal_meter1
                self.spi = self.mix_daqt2.spi
            else:
                self.ipcore = ipcore
                self.signal_meter0 = ipcore.signal_meter0
                self.signal_meter1 = ipcore.signal_meter1
                self.spi = ipcore.spi
            if signal_meter_0 or signal_meter_1 or spi:
                raise MagikException(
                    'Not allowed to use both Integrated IP and Separated IP at the same time!'
                )
        else:
            if signal_meter_0 and signal_meter_1:
                if isinstance(signal_meter_0, basestring):
                    axi4_bus = AXI4LiteBus(signal_meter_0,
                                           MagikDef.SIGNAL_METER_REG_SIZE)
                    self.signal_meter0 = MIXSignalMeterSG(axi4_bus)
                else:
                    self.signal_meter0 = signal_meter_0
                if isinstance(signal_meter_1, basestring):
                    axi4_bus = AXI4LiteBus(signal_meter_1,
                                           MagikDef.SIGNAL_METER_REG_SIZE)
                    self.signal_meter1 = MIXSignalMeterSG(axi4_bus)
                else:
                    self.signal_meter1 = signal_meter_1
            elif not signal_meter_0 and not signal_meter_1:
                self.signal_meter0 = MIXSignalMeterSGEmulator(
                    'mix_signalmeter_sg_emulator', 256)
                self.signal_meter1 = MIXSignalMeterSGEmulator(
                    'mix_signalmeter_sg_emulator', 256)
            else:
                raise MagikException(
                    'signal_meter_0 and signal_meter_1 IP need to exist or be empty at the same time!'
                )
            self.spi = spi if spi else MIXQSPISGEmulator(
                'mix_qspi_sg_emulator', 256)

        if i2c:
            self.cat9555 = CAT9555(MagikDef.CAT9555_ADDR, i2c)
            self.nct75 = NCT75(sensor_dev_addr, i2c)
            self.eeprom = CAT24C32(eeprom_dev_addr, i2c)
        else:
            self.cat9555 = CAT9555Emulator(MagikDef.CAT9555_ADDR, None, None)
            self.eeprom = EepromEmulator('eeprom_emulator')
            self.nct75 = NCT75Emulator('nct75_emulator')

        self.spi.open()
        self.spi.set_speed(MagikDef.SPI_CLOCK_SPEED)
        self.spi.set_mode(MagikDef.SPI_BUS_MODE)
        ad9628_pdwn = Pin(self.cat9555, 6)
        ad9628_oeb = Pin(self.cat9555, 7)
        ad9628_cs = Pin(self.cat9555, 12)
        self.ad9628 = AD9628(self.spi, ad9628_pdwn, ad9628_oeb, ad9628_cs)
        super(MagikBase, self).__init__(self.eeprom,
                                        self.nct75,
                                        cal_table=magik_calibration_info,
                                        range_table=magik_range_table)
Exemple #24
0
    def __init__(self, i2c, ipcore=None, range_table=starlord_table):
        if i2c:
            self.eeprom = CAT24C32(StarLordDef.EEPROM_I2C_ADDR, i2c)
            self.nct75 = NCT75(StarLordDef.TEMP_I2C_ADDR, i2c)
            self.pca9536 = PCA9536(StarLordDef.PCA9536_DEV_ADDR, i2c)

        else:
            self.eeprom = EepromEmulator("cat24cxx_emulator")
            self.nct75 = NCT75Emulator("nct75_emulator")
            self.pca9536 = PCA9536Emulator("PCA9536_emulator")

        if ipcore:
            if isinstance(ipcore, basestring):
                ipcore = MIXAUT5SGR(ipcore)
            self.ipcore = ipcore
            self.analyzer = self.ipcore.analyzer
            self.signal_source = self.ipcore.signal_source
            self.ad7175 = self.ipcore.ad717x
            self.ad7175.config = {
                'ch0': {
                    'P': 'AIN0',
                    'N': 'AIN1'
                },
                'ch1': {
                    'P': 'AIN2',
                    'N': 'AIN3'
                }
            }
            self.adc_rst_pin = Pin(self.ipcore.gpio, StarLordDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = Pin(self.ipcore.gpio,
                                     StarLordDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = Pin(self.ipcore.gpio, StarLordDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = Pin(self.ipcore.gpio,
                                     StarLordDef.I2S_TX_EN_PIN)
            self.i2s_ch_select = [
                Pin(self.ipcore.gpio, StarLordDef.I2S_CH_SELECT_2),
                Pin(self.ipcore.gpio, StarLordDef.I2S_CH_SELECT_3)
            ]
            self.fft_source_select = Pin(self.ipcore.gpio,
                                         StarLordDef.FFT_SOURCE_SELECT)
            self.ad7175_upload_select = Pin(self.ipcore.gpio,
                                            StarLordDef.AD7175_TO_FFT_OR_NOT)

        else:
            self.analyzer = MIXFftAnalyzerSGEmulator(
                "mix_fftanalyzer_sg_emulator")
            self.signal_source = MIXSignalSourceSGEmulator(
                "mix_signalsource_sg_emulator")
            self.adc_rst_pin = Pin(None, StarLordDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = Pin(None, StarLordDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = Pin(None, StarLordDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = Pin(None, StarLordDef.I2S_TX_EN_PIN)
            self.ad7175 = MIXAd7175SGEmulator('mix_ad7175_sg_emulator',
                                              StarLordDef.EMULATOR_REG_SIZE)
            self.i2s_ch_select = [
                Pin(None, StarLordDef.I2S_CH_SELECT_2),
                Pin(None, StarLordDef.I2S_CH_SELECT_3)
            ]
            self.fft_source_select = Pin(None, StarLordDef.FFT_SOURCE_SELECT)
            self.ad7175_upload_select = Pin(None,
                                            StarLordDef.AD7175_TO_FFT_OR_NOT)

        super(StarLord, self).__init__(self.eeprom,
                                       self.nct75,
                                       cal_table={},
                                       range_table=range_table)
        self.is_lna_up = False
        self.is_analyzer_up = False
        self.is_enable_upload = False
Exemple #25
0
class StarLord(MIXBoard):
    '''
    StarLord is a high resolution differential input digital audio analyzer module

    Args:
        i2c:    instance(I2C), the instance of I2C bus. which will be used to used
                               to control eeprom, sensor and io expander.
        ipcore: instance(MIXAUT5SGR), the instance of MIXAUT5SGR, which include
                                    AD717x, FFT Analyzer, Signal Source and gpio
                                    function. If device name string is passed
                                    to the parameter, the ipcore can be instanced
                                    in the module.

    Examples:
        i2c = I2C('/dev/i2c-0')
        starlord = StarLord(i2c, '/dev/MIX_AUT5_SG_R_0')
        starlord.module_init()
        # measure left channel input
        result = starlord.measure('left', 20000, 3)
        print("vpp={}, freq={}, thd={}, thdn={}, rms={}, noisefloor={}".format(result['vpp'],
              result['freq'], result['thd'], result['thdn'], result['rms'],
              result['noisefloor']))

        # measure LNA signal
        result = starlord.measure('left', '50mV', 20000, 3, 1000)
        print("vpp={}, freq={}, thd={}, thdn={}, rms={}".format(result['vpp'],
              result['freq'], result['thd'], result['thdn'], result['rms']))
    '''
    compatible = ['GQQ-AUD003002-000']

    rpc_public_api = [
        'module_init', 'enable_upload', 'disable_upload', 'measure',
        'enable_output', 'disable_output', 'measure_lna', 'enable_lna_upload',
        'disable_lna_upload', 'config_lna_scope'
    ] + MIXBoard.rpc_public_api

    def __init__(self, i2c, ipcore=None, range_table=starlord_table):
        if i2c:
            self.eeprom = CAT24C32(StarLordDef.EEPROM_I2C_ADDR, i2c)
            self.nct75 = NCT75(StarLordDef.TEMP_I2C_ADDR, i2c)
            self.pca9536 = PCA9536(StarLordDef.PCA9536_DEV_ADDR, i2c)

        else:
            self.eeprom = EepromEmulator("cat24cxx_emulator")
            self.nct75 = NCT75Emulator("nct75_emulator")
            self.pca9536 = PCA9536Emulator("PCA9536_emulator")

        if ipcore:
            if isinstance(ipcore, basestring):
                ipcore = MIXAUT5SGR(ipcore)
            self.ipcore = ipcore
            self.analyzer = self.ipcore.analyzer
            self.signal_source = self.ipcore.signal_source
            self.ad7175 = self.ipcore.ad717x
            self.ad7175.config = {
                'ch0': {
                    'P': 'AIN0',
                    'N': 'AIN1'
                },
                'ch1': {
                    'P': 'AIN2',
                    'N': 'AIN3'
                }
            }
            self.adc_rst_pin = Pin(self.ipcore.gpio, StarLordDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = Pin(self.ipcore.gpio,
                                     StarLordDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = Pin(self.ipcore.gpio, StarLordDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = Pin(self.ipcore.gpio,
                                     StarLordDef.I2S_TX_EN_PIN)
            self.i2s_ch_select = [
                Pin(self.ipcore.gpio, StarLordDef.I2S_CH_SELECT_2),
                Pin(self.ipcore.gpio, StarLordDef.I2S_CH_SELECT_3)
            ]
            self.fft_source_select = Pin(self.ipcore.gpio,
                                         StarLordDef.FFT_SOURCE_SELECT)
            self.ad7175_upload_select = Pin(self.ipcore.gpio,
                                            StarLordDef.AD7175_TO_FFT_OR_NOT)

        else:
            self.analyzer = MIXFftAnalyzerSGEmulator(
                "mix_fftanalyzer_sg_emulator")
            self.signal_source = MIXSignalSourceSGEmulator(
                "mix_signalsource_sg_emulator")
            self.adc_rst_pin = Pin(None, StarLordDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = Pin(None, StarLordDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = Pin(None, StarLordDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = Pin(None, StarLordDef.I2S_TX_EN_PIN)
            self.ad7175 = MIXAd7175SGEmulator('mix_ad7175_sg_emulator',
                                              StarLordDef.EMULATOR_REG_SIZE)
            self.i2s_ch_select = [
                Pin(None, StarLordDef.I2S_CH_SELECT_2),
                Pin(None, StarLordDef.I2S_CH_SELECT_3)
            ]
            self.fft_source_select = Pin(None, StarLordDef.FFT_SOURCE_SELECT)
            self.ad7175_upload_select = Pin(None,
                                            StarLordDef.AD7175_TO_FFT_OR_NOT)

        super(StarLord, self).__init__(self.eeprom,
                                       self.nct75,
                                       cal_table={},
                                       range_table=range_table)
        self.is_lna_up = False
        self.is_analyzer_up = False
        self.is_enable_upload = False

    def module_init(self):
        '''
        Init module, which will reset dac/adc, i2s module and load calibration

        Returns:
            string, "done", execution successful.

        Examples:
            starloard.module_init()
        '''
        self.adc_rst_pin.set_dir(StarLordDef.IO_DIR_OUTPUT)
        self.dac_rst_pin.set_dir(StarLordDef.IO_DIR_OUTPUT)
        self.i2s_rx_en_pin.set_dir(StarLordDef.IO_DIR_OUTPUT)
        self.i2s_tx_en_pin.set_dir(StarLordDef.IO_DIR_OUTPUT)
        self.i2s_ch_select[StarLordDef.AUDIO_CHANNEL_SELECT_BIT0].set_dir(
            StarLordDef.IO_DIR_OUTPUT)
        self.i2s_ch_select[StarLordDef.AUDIO_CHANNEL_SELECT_BIT1].set_dir(
            StarLordDef.IO_DIR_OUTPUT)
        self.fft_source_select.set_dir(StarLordDef.IO_DIR_OUTPUT)
        self.ad7175_upload_select.set_dir(StarLordDef.IO_DIR_OUTPUT)

        # reset ADC
        self.adc_rst_pin.set_level(0)
        time.sleep(StarLordDef.RELAY_DELAY_S)
        self.adc_rst_pin.set_level(1)

        # reset DAC
        self.dac_rst_pin.set_level(0)
        time.sleep(StarLordDef.RELAY_DELAY_S)
        self.dac_rst_pin.set_level(1)

        # reset i2s rx
        self.i2s_rx_en_pin.set_level(0)

        # reset i2s tx
        self.i2s_tx_en_pin.set_level(0)

        # io init
        self.pca9536.set_pin_dir(StarLordDef.AD7175_CH_LEFT_CTL_BIT,
                                 StarLordDef.IO_DIR_OUTPUT)
        self.pca9536.set_pin_dir(StarLordDef.AD7175_CH_RIGHT_CTL_BIT,
                                 StarLordDef.IO_DIR_OUTPUT)

        self.pca9536.set_pin(StarLordDef.AD7175_CH_LEFT_CTL_BIT, 0)
        self.pca9536.set_pin(StarLordDef.AD7175_CH_RIGHT_CTL_BIT, 0)

        # ad7175 init
        self.ad7175.channel_init()

        # measure lna config init
        self.config_lna_scope(StarLordDef.CH_LEFT, StarLordDef.LNA_RANGE_5V)

        self.load_calibration()

        return "done"

    def enable_upload(self):
        '''
        Enable module data upload.

        Returns:
            string, "done", execution successful.
        '''
        self.i2s_rx_en_pin.set_level(StarLordDef.I2S_RX_ENABLE)
        self.analyzer.enable_upload()
        self.is_enable_upload = True

        return "done"

    def disable_upload(self):
        '''
        Disable module data upload.

        Returns:
            string, "done", execution successful.
        '''
        self.analyzer.disable_upload()
        self.i2s_rx_en_pin.set_level(StarLordDef.I2S_RX_DISABLE)
        self.is_enable_upload = False

        return "done"

    def measure(self,
                channel,
                bandwidth_hz,
                harmonic_count,
                decimation_type=0xFF,
                sampling_rate=StarLordDef.AUDIO_SAMPLING_RATE):
        '''
        Measure audio input signal, which captures data using CS5361.

        Args:
            channel:         string, ['left', 'right'], select input signal channel.
            bandwidth_hz:    int/string, [42~48000], unit Hz, the signal bandwidth.
            harmonic_count:  int, [2~10], The harmonic count of signal.
            decimation_type: int, [1~255], default 0xFF, sample data decimation.
            sampling_rate:   int, [1~192000], default 192000, unit Hz, ADC sampling rate.

        Returns:
            dict, {'vpp': value, 'freq': value, 'thd': value, 'thdn': value, 'rms': value, 'noisefloor': value},
            measurement result.
        '''
        assert channel in StarLordDef.AUDIO_CHANNEL_LIST

        if self.is_enable_upload is False:
            self.i2s_rx_en_pin.set_level(StarLordDef.I2S_RX_ENABLE)

        pin = self.i2s_ch_select[StarLordDef.AUDIO_CHANNEL_SELECT_BIT0]
        pin.set_level(StarLordDef.AUDIO_CHANNEL_LIST[channel][
            StarLordDef.AUDIO_CHANNEL_SELECT_BIT0])
        pin = self.i2s_ch_select[StarLordDef.AUDIO_CHANNEL_SELECT_BIT1]
        pin.set_level(StarLordDef.AUDIO_CHANNEL_LIST[channel][
            StarLordDef.AUDIO_CHANNEL_SELECT_BIT1])

        self.fft_source_select.set_level(StarLordDef.FFT_SOURCE_FROM_CS5361)

        result = self._analyzer(sampling_rate, decimation_type, bandwidth_hz,
                                harmonic_count)

        range_name = "AUDIO_CS5361_RMS_" + channel

        result['rms'] = (self.calibrate(range_name, result['rms'][0]),
                         StarLordDef.VOLT_UNIT_RMS)

        if self.is_enable_upload is False:
            self.i2s_rx_en_pin.set_level(StarLordDef.I2S_RX_DISABLE)

        return result

    def config_lna_scope(self,
                         channel,
                         scope,
                         adc_upload_ch=StarLordDef.AD7175_UPLOAD_TO_FFT):
        '''
        Config LNA measurement scope

        Args:
            channel:        string, ['left', 'right'], the channel to be upload.
            scope:          string, ['5V', '50mV'], AD7175 measurement range.
            adc_upload_ch:  string, ['dma', 'fft'], default 'fft', AD7175 source data is uploaded to DMA or FFT.

        Returns:
            string, "done",  execution successful.
        '''
        assert channel in StarLordDef.AD7175_CH_LIST
        assert scope in StarLordDef.LNA_SCOPE
        assert adc_upload_ch in StarLordDef.AD7175_UPLOAD_CH

        self.channel = channel
        self.scope = scope
        if scope == StarLordDef.LNA_RANGE_5V:
            self.pca9536.set_pin(StarLordDef.AD7175_CH_LIST[channel],
                                 StarLordDef.SEL_GAIN_1)
        else:
            self.pca9536.set_pin(StarLordDef.AD7175_CH_LIST[channel],
                                 StarLordDef.SEL_GAIN_100)

        self.ad7175_upload_select.set_level(
            StarLordDef.AD7175_UPLOAD_CH[adc_upload_ch])

        return "done"

    def enable_lna_upload(self,
                          channel,
                          sampling_rate=StarLordDef.LNA_SAMPLING_RATE):
        '''
        Enable LNA adc data upload

        Args:
            channel:        string, ['left', 'right'], the channel to be upload.
            sampling_rate:  float, default 250000, unit Hz, AD7175 sampling rate,
                                   please refer to datasheet for more information.

        Returns:
            string, "done",  execution successful.
        '''
        assert channel in StarLordDef.AD7175_CH_LIST

        self.is_lna_up = True
        self.ad7175.disable_continuous_sampling(
            StarLordDef.AD7175_CH_LIST[channel])
        time.sleep(StarLordDef.RELAY_DELAY_S)

        self.ad7175.enable_continuous_sampling(
            StarLordDef.AD7175_CH_LIST[channel], sampling_rate)

        return "done"

    def disable_lna_upload(self, channel):
        '''
        Disable LNA adc data upload

        Args:
            channel:        string, ['left', 'right'], the channel to be upload.

        Returns:
            string, "done", execution successful.
        '''
        assert channel in StarLordDef.AD7175_CH_LIST

        self.is_lna_up = False
        if self.is_analyzer_up is True:
            self.analyzer.disable_upload()
            self.is_analyzer_up = False

        self.ad7175.disable_continuous_sampling(
            StarLordDef.AD7175_CH_LIST[channel])

        return "done"

    def measure_lna(self,
                    bandwidth_hz,
                    harmonic_count,
                    decimation_type=0xFF,
                    sampling_rate=StarLordDef.LNA_SAMPLING_RATE):
        '''
        Measure audio LNA input signal, which captures data using AD7175.

        Args:
            bandwidth_hz:    int/string, [42~48000], unit Hz, the signal bandwidth.
            harmonic_count:  int, [2~10], The harmonic count of signal.
            decimation_type: int, [1~255], default 0xFF, sample data decimation.
            sampling_rate:   int, [5~250000], default 250000, unit Hz,
                                  Sample rate of your ADC device.

        Returns:
            dict, {'vpp': value, 'freq': value, 'thd': value, 'thdn': value, 'rms': value, 'noisefloor': value},
            measurement result.
        '''
        self.fft_source_select.set_level(StarLordDef.FFT_SOURCE_FROM_AD7175)

        if self.is_lna_up is True and self.is_analyzer_up is False:
            self.analyzer.enable_upload()
            self.is_analyzer_up = True

        self.analyzer.disable()
        self.analyzer.enable()
        self.analyzer.analyze_config(sampling_rate, decimation_type,
                                     bandwidth_hz, harmonic_count)
        self.analyzer.analyze()

        range_name = "LNA_" + self.scope + "_" + self.channel
        gain = StarLordDef.GAIN_VALUE[self.scope]
        vpp = self.analyzer.get_vpp() * gain
        rms = vpp / StarLordDef.RMS_TO_VPP_RATIO
        rms = self.calibrate(range_name, rms)
        thdn_value = self.analyzer.get_thdn()

        result = dict()
        result["vpp"] = (vpp, StarLordDef.VOLT_UNIT_MV)
        result["freq"] = (self.analyzer.get_frequency(),
                          StarLordDef.FREQ_UNIT_HZ)
        result["thd"] = (self.analyzer.get_thd(), StarLordDef.THD_UNIT_DB)
        result["thdn"] = (thdn_value, StarLordDef.THDN_UNIT_DB)
        result["rms"] = (rms, StarLordDef.VOLT_UNIT_RMS)
        result["noisefloor"] = (10**(thdn_value / 20) * rms,
                                StarLordDef.VOLT_UNIT_RMS)

        return result

    def enable_output(self, freq, vpp):
        '''
        StarLord CS5361 output audio sine waveform.

        Args:
            freq:       int, [5~50000], unit Hz, output signal's frequency.
            vpp:        float, [0~6504], unit mV, output signal's vpp.

        Returns:
            string, "done", execution successful.
        '''
        assert StarLordDef.OUTPUT_FREQ_MIN <= freq
        assert freq <= StarLordDef.OUTPUT_FREQ_MAX
        assert StarLordDef.OUTPUT_VPP_MIN <= vpp
        assert vpp <= StarLordDef.OUTPUT_VPP_MAX

        vpp = self.calibrate(StarLordDef.OUTPUT_CAL_ITEM, vpp)
        vpp = 0 if vpp < 0 else vpp
        # enable I2S tx module
        self.i2s_tx_en_pin.set_level(StarLordDef.AUDIO_OUTPUT_ENABLE)

        self.signal_source.close()
        self.signal_source.open()
        # calculate vpp to vpp scale for FPGA
        vpp_scale = vpp * StarLordDef.VPP_2_SCALE_RATIO
        self.signal_source.set_swg_paramter(StarLordDef.AUDIO_SAMPLING_RATE,
                                            freq, vpp_scale,
                                            StarLordDef.OUTPUT_SIGNAL_DUTY)
        self.signal_source.set_signal_type(StarLordDef.OUTPUT_WAVE)
        self.signal_source.set_signal_time(StarLordDef.SIGNAL_ALWAYS_OUTPUT)
        self.signal_source.output_signal()

        return "done"

    def disable_output(self):
        '''
        Disable Cs5361 output signal.

        Returns:
            string, "done", execution successful.
        '''
        self.signal_source.close()
        self.i2s_tx_en_pin.set_level(StarLordDef.AUDIO_OUTPUT_DISABLE)

        return "done"

    def _analyzer(self, sampling_rate, decimation_type, bandwidth_hz,
                  harmonic_count):
        '''
        Measure audio input signal.

        Returns:
            dict, {'vpp': value, 'freq': value, 'thd': value, 'thdn': value, 'rms': value, 'noisefloor': value},
            measurement result.
        '''
        self.analyzer.disable()
        self.analyzer.enable()
        self.analyzer.analyze_config(sampling_rate, decimation_type,
                                     bandwidth_hz, harmonic_count)
        self.analyzer.analyze()

        # calculate the actual vpp of HW by VREF
        vpp = self.analyzer.get_vpp() * StarLordDef.AUDIO_ANALYZER_VREF
        # vpp = RMS * 2 * sqrt(2)
        rms = vpp / StarLordDef.RMS_TO_VPP_RATIO
        vpp = rms * StarLordDef.RMS_TO_VPP_RATIO
        thdn_value = self.analyzer.get_thdn()

        result = dict()
        result["vpp"] = (vpp, StarLordDef.VOLT_UNIT_MV)
        result["freq"] = (self.analyzer.get_frequency(),
                          StarLordDef.FREQ_UNIT_HZ)
        result["thd"] = (self.analyzer.get_thd(), StarLordDef.THD_UNIT_DB)
        result["thdn"] = (thdn_value, StarLordDef.THDN_UNIT_DB)
        result["rms"] = (rms, StarLordDef.VOLT_UNIT_RMS)
        result["noisefloor"] = (10**(thdn_value / 20) * rms,
                                StarLordDef.VOLT_UNIT_RMS)

        return result
Exemple #26
0
    def __init__(self,
                 i2c,
                 ad7175=None,
                 range_sel=None,
                 meter_sel=None,
                 ipcore=None):

        if i2c and ad7175 and range_sel and meter_sel and not ipcore:
            if isinstance(ad7175, basestring):
                axi4 = AXI4LiteBus(ad7175, WolverineDef.PLAD7175_REG_SIZE)
                self.ad7175 = MIXAd7175SG(axi4,
                                          mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK)
            else:
                self.ad7175 = ad7175
            self.range_sel = range_sel
            self.meter_sel = meter_sel
        elif i2c and not ad7175 and not range_sel and not meter_sel and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus,
                                          'AD7175',
                                          ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK,
                                          use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            gpio = self.ipcore.gpio
            self.range_sel = Pin(gpio, WolverineDef.RANGE_SEL_BIT)
            self.meter_sel = Pin(gpio, WolverineDef.METER_SEL_BIT)
        elif i2c and not ad7175 and range_sel and meter_sel and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus,
                                          'AD7175',
                                          ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK,
                                          use_gpio=False)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            self.range_sel = range_sel
            self.meter_sel = meter_sel
        elif not i2c and not ad7175 and not range_sel and not meter_sel and not ipcore:
            self.ad7175 = MIXAd7175SGEmulator("ad7175_emulator",
                                              WolverineDef.EMULATOR_REG_SIZE)
            self.range_sel = Pin(None, WolverineDef.RANGE_SEL_BIT)
            self.meter_sel = Pin(None, WolverineDef.METER_SEL_BIT)
        else:
            raise WolverineException("Invalid parameter, please check")
        if i2c:
            eeprom = CAT24C32(WolverineDef.EEPROM_DEV_ADDR, i2c)
            nct75 = NCT75(WolverineDef.NCT75_DEV_ADDR, i2c)
            super(Wolverine,
                  self).__init__(eeprom,
                                 nct75,
                                 cal_table=wolverine_calibration_info,
                                 range_table=wolverine_range_table)
        else:
            super(Wolverine,
                  self).__init__(None,
                                 None,
                                 cal_table=wolverine_calibration_info,
                                 range_table=wolverine_range_table)

        self.channel_path = {
            'range_sel_bit': self.range_sel,
            'meter_sel_bit': self.meter_sel
        }
        self.measure_path = {"channel": None, "range": None}
Exemple #27
0
class Wolverine(MIXBoard):
    '''
    DMM001 is a compact version of the digital multimeter which internal ADC resolution is 24 bit.

    compatible = ["GQQ-DMM001003-000"]

    It can be used as
    high performance DMM to measure DC voltage and small signal DC current. In this class, adc channel 0 is current
    channel, adc channel 1 is voltage channel. DMM001 support signal measurement and continuous measurement. Note that
    if range_ctrl0 and range_ctrl1 not given, internal submodule GPIO device of MIX_DAQT1 will be used to control range.
    Note that calibration default is enabled. This class is legacy driver for normal boot.

    Args:
        i2c:             instance(I2C)/None, which is used to control nct75 and cat24c32. If not given,
                                            emulator will be created.
        ad7175:          instance(ADC)/None, Class instance of AD7175, if not using this parameter, will create emulator
        range_sel:       instance(GPIO),       This can be Pin or xilinx gpio, used to control range.
        meter_sel:       instance(GPIO),       This can be Pin or xilinx gpio, used to control measure channel
        ipcore:          instance(MIXDAQT1SGR)/string,  MIXDAQT1SGR ipcore driver instance or device name string,
                                              if given, user should not use ad7175.


    Examples:
        Example for using no-aggregate IP:
            # normal init
            ad7175 = MIXAd7175SG('/dev/MIX_AD717X_0', 5000)
            i2c = I2C('/dev/i2c-1')
            gpio = GPIO(i2c)
            range_sel = Pin(gpio, 1)
            meter_sel = Pin(gpio, 3)
            wolverine = Wolverine(i2c, ad7175, range_sel=range_sel, meter_sel=meter_sel)

            # using ipcore device name string
            i2c = I2C('/dev/i2c-1')
            gpio = GPIO(i2c)
            range_sel = Pin(gpio, 1)
            meter_sel = Pin(gpio, 3)
            wolverine = Wolverine(i2c, '/dev/MIX_AD717X_0', range_sel=range_sel, meter_sel=meter_sel)


        Example for using aggregate IP:
            # normal init
            i2c = I2C('/dev/i2c-1')
            daqt1 = MIXDAQT1SGR('/dev/MIX_DAQT1', ad717x_chip='AD7175', ad717x_mvref=5000, use_spi=False, use_gpio=True)
            wolverine = Wolverine(i2c, ipcore=daqt1)

            # using ipcore device name
            i2c = I2C('/dev/i2c-1')
            wolverine = Wolverine(i2c, ipcore='/dev/MIX_DAQT1')

        Example for measuring voltage:
            result = wolverine.voltage_measure(5)
            print("voltage={}, unit={}".format(result[0], result[1]))

            result = wolverine.multi_points_voltage_measure(3, 5)
            print("average={}, max={}, min={}, rms={}".format(result['average'], result['max'],
            result['min'], result['rms']))

        Example for measuring current:
            result = wolverine.current_measure('2mA', 5)
            print("current={}, unit={}".format(result[0], result[1]))

            result = wolverine.multi_points_current_measure(3, '2mA', 5)
            print("average={}, max={}, min={}, rms={}".format(result['average'], result['max'],
            result['min'], result['rms']))

    '''
    # launcher will use this to match driver compatible string and load driver if matched.
    compatible = ["GQQ-DMM001003-000"]

    rpc_public_api = [
        'module_init', 'get_sampling_rate', 'set_measure_path',
        'get_measure_path', 'voltage_measure', 'multi_points_voltage_measure',
        'current_measure', 'multi_points_current_measure'
    ] + MIXBoard.rpc_public_api

    def __init__(self,
                 i2c,
                 ad7175=None,
                 range_sel=None,
                 meter_sel=None,
                 ipcore=None):

        if i2c and ad7175 and range_sel and meter_sel and not ipcore:
            if isinstance(ad7175, basestring):
                axi4 = AXI4LiteBus(ad7175, WolverineDef.PLAD7175_REG_SIZE)
                self.ad7175 = MIXAd7175SG(axi4,
                                          mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK)
            else:
                self.ad7175 = ad7175
            self.range_sel = range_sel
            self.meter_sel = meter_sel
        elif i2c and not ad7175 and not range_sel and not meter_sel and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus,
                                          'AD7175',
                                          ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK,
                                          use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            gpio = self.ipcore.gpio
            self.range_sel = Pin(gpio, WolverineDef.RANGE_SEL_BIT)
            self.meter_sel = Pin(gpio, WolverineDef.METER_SEL_BIT)
        elif i2c and not ad7175 and range_sel and meter_sel and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus,
                                          'AD7175',
                                          ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK,
                                          use_gpio=False)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            self.range_sel = range_sel
            self.meter_sel = meter_sel
        elif not i2c and not ad7175 and not range_sel and not meter_sel and not ipcore:
            self.ad7175 = MIXAd7175SGEmulator("ad7175_emulator",
                                              WolverineDef.EMULATOR_REG_SIZE)
            self.range_sel = Pin(None, WolverineDef.RANGE_SEL_BIT)
            self.meter_sel = Pin(None, WolverineDef.METER_SEL_BIT)
        else:
            raise WolverineException("Invalid parameter, please check")
        if i2c:
            eeprom = CAT24C32(WolverineDef.EEPROM_DEV_ADDR, i2c)
            nct75 = NCT75(WolverineDef.NCT75_DEV_ADDR, i2c)
            super(Wolverine,
                  self).__init__(eeprom,
                                 nct75,
                                 cal_table=wolverine_calibration_info,
                                 range_table=wolverine_range_table)
        else:
            super(Wolverine,
                  self).__init__(None,
                                 None,
                                 cal_table=wolverine_calibration_info,
                                 range_table=wolverine_range_table)

        self.channel_path = {
            'range_sel_bit': self.range_sel,
            'meter_sel_bit': self.meter_sel
        }
        self.measure_path = {"channel": None, "range": None}

    def _check_channel(self, channel):
        '''
        Check the channel if it is valid.

        Args:
            channel:  string, ['CURR', 'VOLT'], the channel to check.

        Returns:
            string, ['CURR', 'VOLT'], the channel in specific format.

        Raise:
            WolverineException:  If channel is invalid, exception will be raised.

        '''
        for ch in WolverineDef.CHANNEL_CONFIG:
            if channel.lower() == ch.lower():
                return ch
        raise WolverineException("channel {} is invalid".format(channel))

    def _check_scope(self, channel, scope):
        '''
        Check valid of the specific scope.

        Args:
            channel:     string, the channel to change scope.
            scope:       string, the scope string to be checked.

        Returns:
            string, str, the scope in specific format.

        Raise:
            WolverineException:  If the scope is invalid, exception will be raised.

        '''
        range_config = WolverineDef.CHANNEL_CONFIG[channel]['range']
        for rng in range_config:
            if rng.lower() == scope.lower():
                return rng
        raise WolverineException(
            'scope {} in channel {} is not invalid'.format(channel, scope))

    def module_init(self):
        '''
        Init wolverine module. This function will set io direction to output and set default range to '5V'

        Returns:
            string, "done", api execution successful.

        '''
        self.range_sel.set_dir('output')
        self.meter_sel.set_dir('output')
        self.set_measure_path(WolverineDef.VOLT_5V)
        self.ad7175.channel_init()
        self.set_sampling_rate(WolverineDef.VOLTAGE_CHANNEL,
                               WolverineDef.DEFAULT_SAMPLE_RATE)
        self.set_sampling_rate(WolverineDef.CURRENT_CHANNEL,
                               WolverineDef.DEFAULT_SAMPLE_RATE)
        self.load_calibration()
        return "done"

    def set_sampling_rate(self, channel, sampling_rate):
        '''
        Wolverine set sampling rate.

        Note that sampling rate is not discontinuous, all support sampling
        rate can be found in ad7175 datasheet.

        Args:
            channel:            string, ['VOLT', 'CURR'], the channel to change sampling rate.
            sampling_rate:      float, [5~250000], adc measure sampling rate, which is not continuous,
                                                        please refer to ad7175 datasheet.

        Returns:
            string, "done", api execution successful.

        Examples:
            wolverine.set_sampling_rate('VOLT', 10000)

        '''
        assert 5 <= sampling_rate <= 250000
        channel = self._check_channel(channel)

        if sampling_rate != self.get_sampling_rate(channel):
            self.ad7175.set_sampling_rate(
                WolverineDef.CHANNEL_CONFIG[channel]['adc_channel'],
                sampling_rate)

    def get_sampling_rate(self, channel):
        '''
        Wolverine get sampling rate of adc

        Args:
            channel:            string, ['VOLT', 'CURR'], the channel to get sampling rate.

        Returns:
            int, value, current module sampling rate.

        Examples:
            sampling_rate = wolverine.set_sampling_rate('VOLT')
            print(sampling_rate)

        '''
        channel = self._check_channel(channel)

        return self.ad7175.get_sampling_rate(
            WolverineDef.CHANNEL_CONFIG[channel]['adc_channel'])

    def _get_channel_from_scope(self, scope):
        '''
        Get channel from scope string.

        Args:
            scope:     string, ['5V', '2mA', '100uA'], measure range string.

        Examples:
            string, ['VOLT', 'CURR', wolverine measure channel.

        '''
        if scope.lower() == WolverineDef.VOLT_5V.lower():
            return WolverineDef.VOLTAGE_CHANNEL
        elif scope.lower() in [
                WolverineDef.CURR_2MA.lower(),
                WolverineDef.CURR_100UA.lower()
        ]:
            return WolverineDef.CURRENT_CHANNEL
        else:
            raise WolverineException("scope {} is invalid.".format(scope))

    def set_measure_path(self, scope):
        '''
        Wolverine set measure path.

        Args:
            scope:       string, ['100uA', '2mA', '5V''], set range for different channel

        Returns:
            string, "done", api execution successful.

        Examples:
            wolverine.setmeasure_path('5V')

        '''
        channel = self._get_channel_from_scope(scope)
        scope = self._check_scope(channel, scope)

        path_bits = WolverineDef.CHANNEL_CONFIG[channel]['range'][scope][
            'path']

        if self.measure_path["channel"] != channel or \
                self.measure_path["range"] != scope:
            for bits in path_bits:
                self.channel_path[bits[0]].set_level(bits[1])

        self.measure_path["channel"] = channel
        self.measure_path["range"] = scope

    def get_measure_path(self):
        '''
        Wolverine get measure path.

        Returns:
            dict, current channel and range.

        Examples:
            path = wolverine.get_measure_path()
            printf(path)

        '''
        return self.measure_path

    def voltage_measure(self, sampling_rate=WolverineDef.DEFAULT_SAMPLE_RATE):
        '''
        Wolverine measure voltage once

        Args:
            sampling_rate:  float, [5~250000], default 5, not continuous, please refer to ad7175 datasheet.

        Returns:
            list, [value, 'mV'], voltage value and unit.

        '''

        # Slect range: VOLT_5V = '5V'
        self.set_measure_path(WolverineDef.VOLT_5V)

        # Set sampling_rate
        self.set_sampling_rate(WolverineDef.VOLTAGE_CHANNEL, sampling_rate)

        voltage = self.ad7175.read_volt(WolverineDef.CHANNEL_CONFIG[
            self.measure_path['channel']]['adc_channel'])
        gain = WolverineDef.VOLTAGE_5V_GAIN
        voltage /= gain
        cal_item = self.measure_path["channel"] + "_" + self.measure_path[
            "range"]
        voltage = self.calibrate(cal_item, voltage)

        return [voltage, 'mV']

    def multi_points_voltage_measure(self,
                                     count,
                                     sampling_rate=WolverineDef.
                                     DEFAULT_SAMPLE_RATE):
        '''
        Wolverine measure voltage in continuous mode.

        Notice that before call this function,
        continuous voltage measure has been started.

        Args:
            count:          int, [1~512], Get count voltage in continuous mode.
            sampling_rate:  float, [5~250000], default 5, not continuous, please refer to ad7175 datasheet.

        Returns:
            dict, {"rms":[value, 'mVrms'], "average":[value, 'mV'], "max":[value, 'mV'], "min":[value, 'mV']},
                  rms, average, max and min voltage with unit.

        '''

        adc_channel = WolverineDef.CHANNEL_CONFIG[
            self.measure_path['channel']]['adc_channel']

        # Slect range: VOLT_5V = '5V'
        self.set_measure_path(WolverineDef.VOLT_5V)

        self.ad7175.disable_continuous_sampling(adc_channel)
        time.sleep(WolverineDef.SWITCH_DELAY)
        self.ad7175.enable_continuous_sampling(adc_channel, sampling_rate)
        adc_volt = self.ad7175.get_continuous_sampling_voltage(
            adc_channel, count)
        self.ad7175.disable_continuous_sampling(adc_channel)

        min_data = min(adc_volt)
        max_data = max(adc_volt)
        sum_Data = sum(adc_volt)
        avg_data = sum_Data / len(adc_volt)
        suqare_sum_data = sum([x**2 for x in adc_volt])
        rms_data = math.sqrt(suqare_sum_data / len(adc_volt))

        gain = WolverineDef.VOLTAGE_5V_GAIN

        rms = rms_data / gain
        voltage = avg_data / gain
        max_voltage = max_data / gain
        min_voltage = min_data / gain

        cal_item = self.measure_path["channel"] + "_" + self.measure_path[
            "range"]
        voltage = self.calibrate(cal_item, voltage)

        result = dict()
        result['rms'] = (rms, 'mVrms')
        result['average'] = (voltage, 'mV')
        result['max'] = (max_voltage, 'mV')
        result['min'] = (min_voltage, 'mV')

        return result

    def current_measure(self,
                        curr_range=WolverineDef.CURR_2MA,
                        sampling_rate=WolverineDef.DEFAULT_SAMPLE_RATE):
        '''
        Wolverine measure current once

        Args:
            curr_range:     string, ['2mA', '100uA'], default '2mA', measure range string.
            sampling_rate:  float, [5~250000], default 5, not continuous, please refer to ad7175 datasheet.

        Returns:
            list, [value, 'mA'], current value and unit.

        '''
        assert curr_range in [WolverineDef.CURR_100UA, WolverineDef.CURR_2MA]

        # Slect range: CURR_100UA = '100uA', CURR_2MA = '2mA'
        self.set_measure_path(curr_range)

        # Set sampling_rate
        self.set_sampling_rate(WolverineDef.CURRENT_CHANNEL, sampling_rate)

        volt = self.ad7175.read_volt(WolverineDef.CHANNEL_CONFIG[
            self.measure_path['channel']]['adc_channel'])

        sample_res = WolverineDef.CURRENT_100UA_SAMPLE_RES if \
            self.measure_path["range"] == WolverineDef.CURR_100UA else \
            WolverineDef.CURRENT_2MA_SAMPLE_RES
        gain = WolverineDef.CURRENT_100UA_GAIN if \
            self.measure_path["range"] == WolverineDef.CURR_100UA else \
            WolverineDef.CURRENT_2MA_GAIN
        current = (volt / gain) / sample_res
        cal_item = self.measure_path["channel"] + "_" + self.measure_path[
            "range"]
        current = self.calibrate(cal_item, current)

        return [current, 'mA']

    def multi_points_current_measure(
            self,
            count,
            curr_range=WolverineDef.CURR_2MA,
            sampling_rate=WolverineDef.DEFAULT_SAMPLE_RATE):
        '''
        Wolverine measure current in continuous mode.

        Note that before call this function,
        continuous current measure must be started first

        Args:
            count:           int, [1~512], number current value to be get
            curr_range:      string, ['2mA', '100uA'], default '2mA', measure range string.
            sampling_rate:   float, [5~250000], default 5, not continuous, please refer to ad7175 datasheet.

        Returns:
            dict, {"rms":[value, 'mVrms'], "average":[value, 'mA'], "max":[value, 'mA'], "min":[value, 'mA']},
                  rms, average, max and min current with unit.

        '''
        assert curr_range in [WolverineDef.CURR_100UA, WolverineDef.CURR_2MA]

        adc_channel = WolverineDef.CHANNEL_CONFIG[
            self.measure_path['channel']]['adc_channel']

        # Slect range: CURR_100UA = '100uA', CURR_2MA = '2mA'
        self.set_measure_path(curr_range)

        self.ad7175.disable_continuous_sampling(adc_channel)
        time.sleep(WolverineDef.SWITCH_DELAY)

        self.ad7175.enable_continuous_sampling(adc_channel, sampling_rate)

        adc_volt = self.ad7175.get_continuous_sampling_voltage(
            adc_channel, count)
        self.ad7175.disable_continuous_sampling(adc_channel)

        min_data = min(adc_volt)
        max_data = max(adc_volt)
        sum_Data = sum(adc_volt)
        avg_data = sum_Data / len(adc_volt)
        suqare_sum_data = sum([x**2 for x in adc_volt])
        rms_data = math.sqrt(suqare_sum_data / len(adc_volt))

        sample_res = WolverineDef.CURRENT_100UA_SAMPLE_RES if \
            self.measure_path["range"] == WolverineDef.CURR_100UA else \
            WolverineDef.CURRENT_2MA_SAMPLE_RES
        gain = WolverineDef.CURRENT_100UA_GAIN if \
            self.measure_path["range"] == WolverineDef.CURR_100UA else \
            WolverineDef.CURRENT_2MA_GAIN

        rms = (rms_data / gain) / sample_res
        current = (avg_data / gain) / sample_res
        max_current = (max_data / gain) / sample_res
        min_current = (min_data / gain) / sample_res

        cal_item = self.measure_path["channel"] + "_" + self.measure_path[
            "range"]
        current = self.calibrate(cal_item, current)

        result = dict()
        result['rms'] = (rms, 'mArms')
        result['average'] = (current, 'mA')
        result['max'] = (max_current, 'mA')
        result['min'] = (min_current, 'mA')

        return result

    def legacy_write_calibration_cell(self, unit_index, gain, offset,
                                      threshold):
        '''
        MIXBoard calibration data write

        Args:
            unit_index:   int,    calibration unit index.
            gain:         float,  calibration gain.
            offset:       float,  calibration offset.
            threshold:    float,  if value < threshold, use this calibration unit data.

        Returns:
            string, "done", api execution successful.

        Examples:
            board.write_calibration_cel(0, 1.1, 0.1, 100)

        Raise:
            BoardArgCheckError: unit_index data type is not int type or unit_index < 0.
            calibration unit format:
                Meaning:    Gain,     Offset,   threshold value, Use flag
                Mem size:   4Bytes,   4Bytes,   4Bytes,            Byte
                Data type:  float,    float,    float,            uint8_t
                Formula:    Y = Gain * X  + Offset

        '''
        if not isinstance(unit_index, int) or unit_index < 0:
            raise BoardArgCheckError(
                "calibration unit memory unit_index data type is not int type or unit_index < 0"
            )

        use_flag = self.calibration_info["use_flag"]
        data = (gain, offset, use_flag)
        s = struct.Struct(WolverineDef.WRITE_CAL_DATA_PACK_FORMAT)
        pack_data = s.pack(*data)

        s = struct.Struct(WolverineDef.WRITE_CAL_DATA_UNPACK_FORMAT)
        data = s.unpack(pack_data)
        address = self.calibration_info[
            "unit_start_addr"] + WolverineDef.CAL_DATA_LEN * unit_index
        self.write_eeprom(address, data)
        return "done"

    def legacy_read_calibration_cell(self, unit_index):
        '''
        MIXBoard read calibration data

        Args:
            unit_index: int, calibration unit index.

        Returns:
            dict, {"gain": value, "offset":value, "threshold": value, "is_use": value}.

        Examples:
            data = board.read_calibration_cel(0)
            print(data)

        Raise:
            BoardArgCheckError: unit_index data type is not int type or unit_index < 0.
            calibration unit format:
                Meaning:    Gain,     Offset,   threshold value, Use flag
                Mem size:   4Bytes,   4Bytes,   4Bytes,            Byte
                Data type:  float,    float,    float,            uint8_t
                Formula:    Y = Gain * X  + Offset

        '''
        if not isinstance(unit_index, int) or unit_index < 0:
            raise BoardArgCheckError(
                "calibration unit memory unit_index data type is not int type or unit_index < 0"
            )

        address = self.calibration_info[
            "unit_start_addr"] + WolverineDef.CAL_DATA_LEN * unit_index
        data = self.read_eeprom(address, WolverineDef.READ_CAL_BYTE)

        s = struct.Struct(WolverineDef.READ_CAL_DATA_PACK_FORMAT)
        pack_data = s.pack(*data)

        s = struct.Struct(WolverineDef.READ_CAL_DATA_UNPACK_FORMAT)
        result = s.unpack(pack_data)

        threshold = 0.0
        for cal_item in wolverine_calibration_info:
            for level in wolverine_calibration_info[cal_item]:
                if unit_index == wolverine_calibration_info[cal_item][level][
                        "unit_index"]:
                    threshold = wolverine_calibration_info[cal_item][level][
                        "limit"][0]

        if self.calibration_info["use_flag"] != result[2]:
            return {"gain": 1.0, "offset": 0.0, "threshold": 0, "is_use": True}
        else:
            return {
                "gain": result[0],
                "offset": result[1],
                "threshold": threshold,
                "is_use": True
            }
Exemple #28
0
class Wolverine(SGModuleDriver):
    '''
    Wolverine is a compact version of the digital multimeter which internal ADC resolution is 24 bit.

    It can be used as
    high performance DMM to measure DC voltage and small signal DC current. In this class, adc channel 0 is current
    channel, adc channel 1 is voltage channel. DMM001 support signal measurement and continuous measurement. Note that
    if range_ctrl0 and range_ctrl1 not given, internal submodule GPIO device of MIX_DAQT1 will be used to control range.
    Note that calibration default is enabled. This class is legacy driver for normal boot.

    Args:
        i2c:             instance(I2C)/None,   which is used to control nct75 and cat24c32. If not given,
                                               emulator will be created.
        ad7175:          instance(ADC)/None,   Class instance of AD7175, if not using this parameter,
                                               will create emulator
        range_ctrl_pin:  instance(GPIO),       This can be Pin or xilinx gpio, used to control range.
        meter_ctrl_pin:  instance(GPIO),       This can be Pin or xilinx gpio, used to control measure channel
        ipcore:          instance(MIXDAQT1SGR)/string,  MIXDAQT1SGR ipcore driver instance or device name string,
                                                        if given, user should not use ad7175.


    Examples:
        Example for using no-aggregate IP:
            # normal init
            ad7175 = MIXAd7175SG('/dev/MIX_AD717X_0', 5000)
            i2c = I2C('/dev/i2c-1')
            gpio = GPIO(i2c)
            range_ctrl_pin = Pin(gpio, 1)
            meter_ctrl_pin = Pin(gpio, 3)
            wolverine = Wolverine(i2c, ad7175, range_ctrl_pin=range_ctrl_pin, meter_ctrl_pin=meter_ctrl_pin)

            # using ipcore device name string
            i2c = I2C('/dev/i2c-1')
            gpio = GPIO(i2c)
            range_ctrl_pin = Pin(gpio, 1)
            meter_ctrl_pin = Pin(gpio, 3)
            wolverine = Wolverine(i2c, '/dev/MIX_AD717X_0', range_ctrl_pin=range_ctrl_pin,
                                  meter_ctrl_pin=meter_ctrl_pin)

        Example for using aggregate IP:
            # normal init
            i2c = I2C('/dev/i2c-1')
            daqt1 = MIXDAQT1SGR('/dev/MIX_DAQT1', ad717x_chip='AD7175', ad717x_mvref=5000, use_spi=False, use_gpio=True)
            wolverine = Wolverine(i2c, ipcore=daqt1)

            # using ipcore device name
            i2c = I2C('/dev/i2c-1')
            wolverine = Wolverine(i2c, ipcore='/dev/MIX_DAQT1')

        Example for measuring voltage/current:
            wolverine.disable_continuous_sampling()
            wolverine.set_measure_path('5V')
            result = wolverine.read_measure_value()
            print("voltage={}, unit is mV".format(result))
            result = wolverine.read_measure_list(count=5)
            print("voltage_list={}, unit is mV".format(result))

            wolverine.set_measure_path('2mA')
            result = wolverine.read_measure_value()
            print("voltage={}, unit is mA".format(result))
            result = wolverine.read_measure_list(count=5)
            print("voltage_list={}, unit is mA".format(result))

        Example for continuous measuring:
            wolverine.enable_continuous_sampling('5V')
            result = wolverine.read_continuous_sampling_statistics(256)
            print("5V Result: average={}, max={}, min={}, rms={}".format(result['avg_v1'],
            result['max_v1'], result['min_v1'], result['rms_v1']))

            wolverine.enable_continuous_sampling('2mA')
            result = wolverine.read_continuous_sampling_statistics(256)
            print("2mA Result: average={}, max={}, min={}, rms={}".format(result['avg_i'],
            result['max_i'], result['min_i'], result['rms_i']))

    '''
    # launcher will use this to match driver compatible string and load driver if matched.
    compatible = ["GQQ-LTJW-5-030"]

    rpc_public_api = [
        'set_sinc', 'get_sampling_rate', 'set_measure_path', 'get_measure_path',
        'read_measure_value', 'read_measure_list',
        'enable_continuous_sampling',
        'disable_continuous_sampling',
        'read_continuous_sampling_statistics', 'datalogger_start',
        'datalogger_end'
    ] + SGModuleDriver.rpc_public_api

    def __init__(self, i2c, ad7175=None, range_ctrl_pin=None,
                 meter_ctrl_pin=None, ipcore=None):

        if ad7175 and range_ctrl_pin and meter_ctrl_pin and not ipcore:
            if isinstance(ad7175, basestring):
                axi4 = AXI4LiteBus(ad7175, WolverineDef.PLAD7175_REG_SIZE)
                self.ad7175 = MIXAd7175SG(axi4, mvref=WolverineDef.MVREF, code_polar=WolverineDef.POLAR,
                                          clock=WolverineDef.CLOCK)
            else:
                self.ad7175 = ad7175
            self.range_ctrl_pin = range_ctrl_pin
            self.meter_ctrl_pin = meter_ctrl_pin
        elif not ad7175 and not range_ctrl_pin and not meter_ctrl_pin and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus, 'AD7175', ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR, clock=WolverineDef.CLOCK, use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            gpio = self.ipcore.gpio
            self.range_ctrl_pin = Pin(gpio, WolverineDef.RANGE_SEL_BIT)
            self.meter_ctrl_pin = Pin(gpio, WolverineDef.METER_SEL_BIT)
            self.tag_pins = [
                Pin(gpio, WolverineDef.TAG_BASE_PIN + x,
                    WolverineDef.GPIO_OUTPUT_DIR) for x in range(4)
            ]
        elif not ad7175 and range_ctrl_pin and meter_ctrl_pin and ipcore:
            if isinstance(ipcore, basestring):
                axi4_bus = AXI4LiteBus(ipcore, WolverineDef.MIX_DAQT1_REG_SIZE)
                self.ipcore = MIXDAQT1SGR(axi4_bus, 'AD7175', ad717x_mvref=WolverineDef.MVREF,
                                          code_polar=WolverineDef.POLAR, clock=WolverineDef.CLOCK, use_gpio=True)
            else:
                self.ipcore = ipcore
            self.ad7175 = self.ipcore.ad717x
            self.range_ctrl_pin = range_ctrl_pin
            self.meter_ctrl_pin = meter_ctrl_pin
            gpio = self.ipcore.gpio
            self.tag_pins = [
                Pin(gpio, WolverineDef.TAG_BASE_PIN + x,
                    WolverineDef.GPIO_OUTPUT_DIR) for x in range(4)
            ]
        else:
            raise WolverineException("Invalid parameter, please check")

        eeprom = CAT24C32(WolverineDef.EEPROM_DEV_ADDR, i2c)
        nct75 = NCT75(WolverineDef.NCT75_DEV_ADDR, i2c)
        super(Wolverine, self).__init__(eeprom, nct75, range_table=wolverine_range_table)

        self.channel_path = {'range_sel_bit': self.range_ctrl_pin, 'meter_sel_bit': self.meter_ctrl_pin}
        self.measure_path = dict()
        self.measure_path['range'] = WolverineDef.VOLT_5V

    def post_power_on_init(self, timeout=WolverineDef.TIME_OUT):
        '''
        Init wolverine module to a know harware state.

        This function will set io direction to output and set default range to '5V'.

        Args:
            timeout:      float, unit Second, execute timeout

        '''
        self.reset(timeout)
        self.load_calibration()
        return "done"

    def reset(self, timeout=WolverineDef.TIME_OUT):
        '''
        Reset the instrument module to a know hardware state.

        Args:
            timeout:      float, unit Second, execute timeout.

        '''
        self.range_ctrl_pin.set_dir('output')
        self.meter_ctrl_pin.set_dir('output')
        self.set_measure_path(WolverineDef.VOLT_5V)
        self.ad7175.channel_init()
        self.set_sampling_rate(WolverineDef.DEFAULT_SAMPLE_RATE)

    def get_driver_version(self):
        '''
        Get wolverine driver version.

        Returns:
            string, current driver version.

        '''
        return __version__

    def write_module_calibration(self, channel, calibration_vectors):
        '''
        Calculate module calibration and write to eeprom.

        Xavier timestamp must be synced with host first before call this function.
        All channels must be calibrated in one day.

        Args:
            channel:        string, ['5V', '2mA', '100uA'], voltage or current channel
            calibration_vectors: list, it contains value pairs of module reading and benchmark
                                 value got from external equipemnets. [[module_raw1,benchmark1],
                                 [module_raw1,benchmark2],
                                 ...
                                 [module_rawN,benchmarkN]]

        Returns:
            string, 'done', execute successful.

        '''
        assert channel in ['5V', '100uA', '2mA']
        return super(Wolverine, self).write_module_calibration(channel, calibration_vectors)

    def set_sinc(self, channel, sinc):
        '''
        wolverineii set digtal filter.

        Args:
            channel:    string, ['100uA', '2mA', '5V'], set range for different channel.
            sinc:       string, ["sinc5_sinc1", "sinc3"]

        Example:
            wolverineii.set_sinc("100uA", "sinc5_sinc1")

        '''
        assert channel in WolverineDef.CHANNEL_CONFIG.keys()
        assert sinc in WolverineDef.ADC_SINC_SEL

        self.ad7175.set_sinc(WolverineDef.CHANNEL_CONFIG[channel]['adc_channel'], sinc)

    def set_sampling_rate(self, sampling_rate):
        '''
        wolverine set sampling rate.

        Note that sampling rate is not discontinuous, all support sampling
        rate can be found in ad7175 datasheet.

        Args:
            sampling_rate:      float, [5~250000], adc measure sampling rate, which is not continuous,
                                                        please refer to ad7175 datasheet.

        Returns:
            string, "done", api execution successful.

        '''
        assert 5 <= sampling_rate <= 250000

        channel = self.measure_path['range']
        if sampling_rate != self.get_sampling_rate(channel):
            self.ad7175.set_sampling_rate(WolverineDef.CHANNEL_CONFIG[channel]['adc_channel'], sampling_rate)

    def get_sampling_rate(self, channel=WolverineDef.VOLT_5V):
        '''
        wolverine Read the sampling rate setting

        Args:
            channel:            string, ['5V', '2mA', '100uA'], get sampling rate for different channel.

        Returns:
            int, value, current module sampling rate in SPS.

        '''
        assert channel in WolverineDef.CHANNEL_CONFIG.keys()

        return self.ad7175.get_sampling_rate(WolverineDef.CHANNEL_CONFIG[channel]['adc_channel'])

    def set_measure_path(self, channel=WolverineDef.VOLT_5V):
        '''
        wolverine set measure path.

        Args:
            channel:       string, ['100uA', '2mA', '5V'], set range for different channel

        Returns:
            string, "done", api execution successful.

        '''
        assert channel in WolverineDef.CHANNEL_CONFIG.keys()

        if channel != self.get_measure_path():
            path_bits = WolverineDef.CHANNEL_CONFIG[channel]['path']
            for bits in path_bits:
                self.channel_path[bits[0]].set_level(bits[1])

            time.sleep(WolverineDef.RELAY_DELAY_S)

        self.measure_path.clear()
        self.measure_path[WolverineDef.SELECT_RANGE_KEY] = channel

        return "done"

    def get_measure_path(self):
        '''
        wolverine get measure path.

        Returns:
            dict, current channel and range.

        '''
        return self.measure_path

    def read_measure_value(self, sample_rate=WolverineDef.DEFAULT_SAMPLE_RATE,
                           count=WolverineDef.DEFAULT_COUNT):
        '''
        Read current average value. The returned value is calibrated if calibration mode is `cal`

        Args:
            sample_rate (int, optional): set sampling rate of data acquisition, in SPS. Default 1000
            count (int, optional): samples count taken for averaging. Default 1

        Returns:
            Int:   measured value defined by set_measure_path()

                   Voltage Channel always in mV

                   Current Channel always in mA
        '''
        assert isinstance(sample_rate, int)
        assert isinstance(count, int) and count >= 1

        measure_path = self.get_measure_path()
        adc_channel = WolverineDef.CHANNEL_CONFIG[measure_path['range']]['adc_channel']

        self.set_sampling_rate(sample_rate)

        cal_item = WolverineDef.CURRENT_CHANNEL + "_" + measure_path['range']
        if measure_path['range'] == WolverineDef.VOLT_5V:
            gain = WolverineDef.VOLTAGE_5V_GAIN
            cal_item = WolverineDef.VOLTAGE_CHANNEL + "_" + measure_path['range']
        elif measure_path['range'] == WolverineDef.CURR_100UA:
            gain = WolverineDef.CURRENT_100UA_GAIN
            sample_res = WolverineDef.CURRENT_100UA_SAMPLE_RES
        else:
            gain = WolverineDef.CURRENT_2MA_GAIN
            sample_res = WolverineDef.CURRENT_2MA_SAMPLE_RES

        target_data = list()
        for x in range(count):
            voltage = self.ad7175.read_volt(adc_channel)
            adc_value = (voltage / gain) if \
                measure_path['range'] == WolverineDef.VOLT_5V else \
                voltage / gain / sample_res
            adc_value = self.calibrate(cal_item, adc_value)
            target_data.append(adc_value)

        target_value = sum(target_data) / count

        return target_value

    def read_measure_list(self, sample_rate=WolverineDef.DEFAULT_SAMPLE_RATE,
                          count=WolverineDef.DEFAULT_COUNT):
        '''
        For example if count is 5, the return list can be: [3711, 3712, 3709, 3703, 3702].

        The returned value is calibrated if calibration mode is `cal`

        Args:
            sample_rate (int, optional): set sampling rate of data acquisition, in SPS. Default 1000
            count (int, optional): samples count taken for averaging. Default 1

        Returns:
            List:   measured value defined by set_measure_path()
                    Voltage Channel always in mV
                    Current Channel always in mA
        '''
        assert isinstance(sample_rate, int)
        assert isinstance(count, int) and count >= 1

        measure_path = self.get_measure_path()
        adc_channel = WolverineDef.CHANNEL_CONFIG[measure_path['range']]['adc_channel']

        self.set_sampling_rate(sample_rate)

        cal_item = WolverineDef.CURRENT_CHANNEL + "_" + measure_path['range']
        if measure_path['range'] == WolverineDef.VOLT_5V:
            gain = WolverineDef.VOLTAGE_5V_GAIN
            cal_item = WolverineDef.VOLTAGE_CHANNEL + "_" + measure_path['range']
        elif measure_path['range'] == WolverineDef.CURR_100UA:
            gain = WolverineDef.CURRENT_100UA_GAIN
            sample_res = WolverineDef.CURRENT_100UA_SAMPLE_RES
        else:
            gain = WolverineDef.CURRENT_2MA_GAIN
            sample_res = WolverineDef.CURRENT_2MA_SAMPLE_RES

        target_data = list()
        for x in range(count):
            voltage = self.ad7175.read_volt(adc_channel)
            adc_value = (voltage / gain) if \
                measure_path['range'] == WolverineDef.VOLT_5V else \
                (voltage / gain / sample_res)
            adc_value = self.calibrate(cal_item, adc_value)
            target_data.append(adc_value)

        return target_data

    def enable_continuous_sampling(self, channel=WolverineDef.VOLT_5V,
                                   sample_rate=WolverineDef.DEFAULT_SAMPLE_RATE,
                                   down_sample=WolverineDef.DEFAULT_DOWN_SAMPLE,
                                   selection=WolverineDef.DEFAULT_SELECTION):
        '''
        This function enables continuous sampling and data throughput upload to upper stream.
        Down sampling is supported.
        For example: when down_sample =5, selection=max, select the maximal value from every 5
            samples, so the actual data rate is reduced by 5.
        The output data inflow is calibrated if calibration mode is `cal`
        During continuous sampling, the setting functions, like set_calibration_mode(),
            set_measure_path(), cannot be called.

        Args:
            channel (string):   '5V':       voltage channel #1
                                '100uA':    100uA current channel
                                '2mA':      2mA current channel
                                Default:    5V
            sample_rate (int):  set sampling rate of data acquisition, in SPS. Default 1000
            down_sample (int):  down sample rate for decimation.
            selection (string): 'max'|'min'. This parameter takes effect as long as down_sample is
                                    higher than 1. Default 'max'

        Returns:
            Str: 'done'
        '''
        assert channel in WolverineDef.CHANNEL_CONFIG.keys()

        adc_channel = WolverineDef.CHANNEL_CONFIG[channel]['adc_channel']
        self.ad7175.disable_continuous_sampling(adc_channel)
        time.sleep(WolverineDef.SWITCH_DELAY)
        self.ad7175.enable_continuous_sampling(adc_channel, sample_rate,
                                               down_sample, selection)

        self.measure_path[WolverineDef.SELECT_RANGE_KEY] = channel

        return "done"

    def disable_continuous_sampling(self):
        '''
        This function disables continuous sampling and data throughput upload to upper stream.
        This function can only be called in continuous mode, a.k.a, after enable_continuous_sampling()
            function is called.

        Returns:
            Str: 'done'
        '''

        measure_path = self.get_measure_path()
        adc_channel = WolverineDef.CHANNEL_CONFIG[measure_path['range']]['adc_channel']
        self.ad7175.disable_continuous_sampling(adc_channel)

        return "done"

    def read_continuous_sampling_statistics(self,
                                            count=WolverineDef.DEFAULT_COUNT):
        '''
        This function takes a number of samples to calculate RMS/average/max/min value of the set of
            sampled value.This function can only be called in continuous mode, a.k.a, after
            enable_continuous_sampling() function is called. Return 0 for the channels that are not enabled.

        The returned value is calibrated if calibration mode is `cal`

        Args:
            count (int): samples count taken for calculation. Default 1

        Returns:
            Dict: {
                (rms_v1, <RMS in mVrms>),
                (avg_v1, <average in mVrms>),
                (max_v1, <maximal in mV>),
                (min_v1, <minimal in mV>),
                (rms_i, <RMS in mArms>),
                (avg_i, <average in mArms>),
                (max_i, <maximal in mA>),
                (min_i, <minimal in mA>)
            }
            for voltage voltage channel #1 and #2.
        '''

        assert isinstance(count, int) and count >= 1

        measure_path = self.get_measure_path()
        adc_channel = WolverineDef.CHANNEL_CONFIG[measure_path['range']]['adc_channel']

        channel_data = list()
        try:
            channel_data = self.ad7175.get_continuous_sampling_voltage(
                adc_channel, count)
        except Exception:
            raise

        min_data = min(channel_data)
        max_data = max(channel_data)
        sum_Data = sum(channel_data)
        avg_data = sum_Data / len(channel_data)
        suqare_sum_data = sum([x**2 for x in channel_data])
        rms_data = math.sqrt(suqare_sum_data / len(channel_data))

        result = dict()
        cal_item = WolverineDef.CURRENT_CHANNEL + "_" + measure_path['range']
        suffix = WolverineDef.CHANNEL_CONFIG[measure_path['range']]['suffix']
        if measure_path['range'] == WolverineDef.VOLT_5V:
            gain = WolverineDef.VOLTAGE_5V_GAIN
            rms = rms_data / gain
            voltage = avg_data / gain
            max_voltage = max_data / gain
            min_voltage = min_data / gain
            cal_item = WolverineDef.VOLTAGE_CHANNEL + "_" + measure_path['range']
            voltage = self.calibrate(cal_item, voltage)

            result['rms_' + suffix] = (rms, 'mVrms')
            result['avg_' + suffix] = (voltage, 'mV')
            result['max_' + suffix] = (max_voltage, 'mV')
            result['min_' + suffix] = (min_voltage, 'mV')
            return result
        elif measure_path['range'] == WolverineDef.CURR_100UA:
            gain = WolverineDef.CURRENT_100UA_GAIN
            sample_res = WolverineDef.CURRENT_100UA_SAMPLE_RES
        else:
            gain = WolverineDef.CURRENT_2MA_GAIN
            sample_res = WolverineDef.CURRENT_2MA_SAMPLE_RES

        rms = (rms_data / gain) / sample_res
        current = (avg_data / gain) / sample_res
        max_current = (max_data / gain) / sample_res
        min_current = (min_data / gain) / sample_res
        current = self.calibrate(cal_item, current)

        result['rms_' + suffix] = (rms, 'mArms')
        result['avg_' + suffix] = (current, 'mA')
        result['max_' + suffix] = (max_current, 'mA')
        result['min_' + suffix] = (min_current, 'mA')
        return result

    def datalogger_start(self, tag=0):
        '''
        Start labeling the samples for on a period of time for calculation.
        This function can only be called in continuous mode, a.k.a, after
        enable_continuous_sampling() function is called.

        Lable shall be on both channels if they are both enabled.

        Args:
            tag (int,  [0, 0x0f]): the value is low 4 bits are valid, from 0x00 to 0x0f.

        Returns:
            Str: 'done'
        '''

        assert tag & 0x0f == tag
        for i in range(4):
            self.tag_pins[i].set_level((tag >> i) & 0x1)

        return "done"

    def datalogger_end(self):
        '''
        Stop labeling the samples. This function can only be called after
            enable_continuous_sampling() and datalogger_start() are called.

        Returns:
            Str: 'done'
        '''

        for i in range(4):
            self.tag_pins[i].set_level(0)

        return "done"
Exemple #29
0
class AD9628(object):
    '''
    The AD9628 is a monolithic, dual-channel, 1.8V supply, 12-bit, 125MSPS/105MSPS analog-to-digital converter (ADC).
    It features a high performance sample-and-hold circuit and onchip voltage reference.
    The digital output data is presented in offset binary, Gray code, or twos complement format.
    A data output clock (DCO) is provided for each ADC channel to ensure proper latch timing with receiving logic.
    1.8V CMOS or LVDS output logic levels are supported. Output data can also be multiplexed onto a single output bus.

    ClassType = ADC

    Args:
        spi_bus:     instance(QSPI)/None,  MIXQSPISG class instance, if not using, will create emulator.
        pdwn_ctrl:   instance(GPIO)/None,  Class instance of GPIO, which is used to control ad9628 pdwn_ctrl signal,
                                           default None for not use.
        oeb_ctrl:    instance(GPIO)/None,  Class instance of GPIO, which is used to control ad9628 oeb_ctrl signal,
                                           default None for not use.
        cs_ctrl:     instance(GPIO)/None,  Class instance of GPIO, which is used to control ad9628 cs_ctrl signal,
                                           default None for not use.
        use_cs:      Bool('True'/'False'), determine if CS is used internally.

    Examples:
        pdwn_ctrl = GPIO(cat9555, 6)
        oeb_ctrl = GPIO(cat9555, 7)
        cs_ctrl = GPIO(cat9555, 12)
        axi4_bus = AXI4LiteBus('/dev/MIX_DUT_SPI_0', 256)
        spi_bus = MIXQSPISG(axi4_bus)
        ad9628 = AD9628(spi_bus, pdwn_ctrl, oeb_ctrl, cs_ctrl)

    '''

    def __init__(self, spi_bus=None, pdwn_ctrl=None, oeb_ctrl=None, cs_ctrl=None, use_cs=True):
        if(spi_bus is None and pdwn_ctrl is None and oeb_ctrl is None):
            self.spi_bus = MIXQSPISGEmulator("ad9628_emulator", 256)
            self.pdwn = Pin(None, 6)
            self.oeb = Pin(None, 7)
        elif(spi_bus is not None and pdwn_ctrl is not None and oeb_ctrl is not None):
            self.spi_bus = spi_bus
            self.pdwn = pdwn_ctrl
            self.oeb = oeb_ctrl
        else:
            raise AD9628RException('__init__ error! Please check the parameters')

        self.use_cs = use_cs
        if(self.use_cs is True and cs_ctrl is not None):
            self.cs = cs_ctrl
        elif(self.use_cs is False and cs_ctrl is None):
            self.cs = Pin(None, 12)
        else:
            raise AD9628RException('cs use error! Please check the parameters')

    def read_register(self, reg_addr):
        '''
        AD9628 internal function to read register

        Args:
            reg_addr:    hexmial, [0~0x102], The register range is 0-0x102 in datasheet, register to be read.

        Returns:
            int, value, register read data.

        Examples:
            rd_data = ad9628.read_register(0x01)
            print(rd_data)
            # rd_data will be like 0x05

        '''
        assert isinstance(reg_addr, int)
        assert 0 <= reg_addr <= 0x102

        if self.use_cs is True:
            self.cs.set_level(0)

        reg_address = (1 << 15) + (reg_addr & 0x3FF)
        read_data = 0
        write_date = [(reg_address >> 8) & 0xFF, reg_address & 0xFF]
        reg_value = self.spi_bus.transfer(write_date, 1, False)
        read_data = reg_value[0]

        if self.use_cs is True:
            self.cs.set_level(1)

        return read_data

    def write_register(self, reg_addr, reg_value):
        '''
        AD9628 internal function to write register

        Args:
            reg_addr:     hexmial, [0~0x102], register to be write.
            reg_value:    hexmial, [0~0xff], data to be write.

        Examples:
            ad9628.write_register(0x01, 0x02)

        '''
        assert isinstance(reg_addr, int)
        assert isinstance(reg_value, int)
        assert 0 <= reg_addr <= 0x102
        assert 0 <= reg_value <= 0xFF

        if self.use_cs is True:
            self.cs.set_level(0)

        reg_address = reg_addr & 0x3FF
        write_date = [(reg_address >> 8) & 0xFF, reg_address & 0xFF, reg_value]
        ret = self.spi_bus.write(write_date)

        if self.use_cs is True:
            self.cs.set_level(1)

        if ret is False:
            return False

        return True

    def get_chip_id(self):
        '''
        AD9628 internal function to get AD9628's chip ID number

        Returns:
            int, value, variable which to store the chip ID.

        Examples:
            id = ad9628.get_chip_id()
            print(id)

        '''
        chip_id = self.read_register(AD9628Def.REGISTER_ADDRESS["chip_id"])
        return chip_id

    def get_clock_speed_grade(self):
        '''
        AD9628 internal function to check AD9628's input clock speed supported, 105000000SPS or 125000000SPS.

        Returns:
            int, value, Return 105000000SPS or 125000000SPS.

        Examples:
            grade = ad9628.clock_speed_grade()
            print(grade)

        '''
        grade = 0
        rd_data = self.read_register(
            AD9628Def.REGISTER_ADDRESS["chip_grade_id"])
        if (((rd_data) >> 4) & 0x07) == 0x04:
            grade = 105000000
        elif (((rd_data) >> 4) & 0x07) == 0x05:
            grade = 125000000
        else:
            raise AD9628RException('get clock speed grade fail!')

        return grade

    def select_channel(self, channel):
        '''
        AD9628 internal function to select which channel to receive SPI command.

        Args:
            channel:    string, ["A", "B", "BOTH"]. select which channel to receive SPI command.

        Examples:
            ad9628.select_channel("A")

        '''
        assert channel in AD9628Def.CHANNEL_SELECT

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["device_index"], AD9628Def.CHANNEL_SELECT[channel])

    def get_sampling_rate(self):
        '''
        AD9628 internal function to get sample rate.

        Returns:
            int, value, Return 80000000SPS, 105000000SPS or 125000000SPS.

        Examples:
            rate = ad9628.get_sampling_rate()
            print(rate)

        '''

        sample_rate = 0
        rd_data = self.read_register(AD9628Def.REGISTER_ADDRESS["sample_rate"])

        if (rd_data & 0x07) == 0x03:
            sample_rate = 80000000
        elif (rd_data & 0x07) == 0x04:
            sample_rate = 105000000
        elif (rd_data & 0x07) == 0x05:
            sample_rate = 125000000
        else:
            raise AD9628RException('get sampling rate fail!')

        return sample_rate

    def setup(self, type, format, msps, bits):
        '''
        AD9628 internal function to Initial AD9628.

        Args:
            type:    string, ["CMOS", "LVDS_ANSI", "LVDS_REDUCED"],
                             configure the data output type of the AD9628.
            format:  string, ["OFFSET_BIN", "TWOS_COMPLEMENT", "GRAY_CODE"],
                             configure the data output format of the AD9628.
            msps:    int, [80000000, 105000000, 125000000],
                          configure the sample speed of data output of the AD9628.
            bits:    string, ["WIDTH_10", "WIDTH_12"],
                             configure the output data bits of the AD9628.

        Examples:
            ad9628.setup("LVDS_ANSI", "OFFSET_BIN", "125000000", "WIDTH_12")

        '''
        assert type in AD9628Def.OUTPUT_TYPE
        assert format in AD9628Def.OUTPUT_FORMAT
        assert msps in AD9628Def.SAMPLE_SPEED
        assert bits in ["WIDTH_10", "WIDTH_12"]

        # Digital Output Enable Function
        self.oeb.set_level(0)
        # self.pdwn.set_level(0), external power down.
        self.power_mode("EXTERNAL", "POWER_DOWN")
        # Internal power-down mode ,register digital reset.
        self.power_mode("INTERNAL", "DIGITAL_RESET")
        # Set power mode need to reset it and wait 1 millisecond
        time.sleep(AD9628Def.SLEEP_TIME)
        self.power_mode("INTERNAL", "POWER_ON")

        output_mode = AD9628Def.OUTPUT_TYPE[type] | AD9628Def.OUTPUT_FORMAT[format]
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["output_mode"], output_mode)

        sample_rate_bits = AD9628Def.RESOLUTION_12_BITS
        if bits == "WIDTH_10":
            sample_rate_bits = AD9628Def.RESOLUTION_10_BITS
        elif bits == "WIDTH_12":
            sample_rate_bits = AD9628Def.RESOLUTION_12_BITS
        else:
            raise AD9628RException('width bits set fail!')
        sample = AD9628Def.SAMPLE_SPEED[msps] | sample_rate_bits
        self.write_register(AD9628Def.REGISTER_ADDRESS["sample_rate"], sample)

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["transfer_addr"], AD9628Def.SYNC_TRANSFER)

    def clock_phase(self, dco_invert_ctrl, phase_ratio):
        '''
        AD9628 internal function to input clock divider phase adjust relative to the encode clock.

        Args:
            dco_invert_ctrl:    string, ["NOT_INVERT", "INVERT"],
                                        control DCO(dat clock output) invert or not.
            phase_ratio:        string, ["NO_DELAY", "ONE_INPUT", "TWO_INPUT", "THREE_INPUT",
                                         "FOUR_INPUT", "FIVE_INPUT", "SIX_INPUT", "SEVEN_INPUT"],
                                        selection of clock delays into the input clock divider.

        Examples:
            ad9628.clock_phase("INVERT", "ONE_INPUT")

        '''
        assert dco_invert_ctrl in ["NOT_INVERT", "INVERT"]
        assert phase_ratio in AD9628Def.PHASE_INPUT_CLOCK_CYCLES

        phase_delay = AD9628Def.PHASE_INPUT_CLOCK_CYCLES[phase_ratio]
        if dco_invert_ctrl == "INVERT":
            phase_con = (AD9628Def.INVERT_DCO | phase_delay)
        else:
            phase_con = (AD9628Def.NOT_INVERT_DCO | phase_delay)

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["clock_phase"], phase_con)

    def clock_divide(self, divide_ratio, div_next_sync, div_sync_en):
        '''
        AD9628 internal function to config clock divider's divide ratio.

        Args:
            divide_ratio:     string, ["BY_1", "BY_2", "BY_3", "BY_4", "BY_5", "BY_6", "BY_7", "BY_8"],
                                      config clock divider's divide ratio.
            div_next_sync:    string, ["NEX_SYNC", "NEX_ASYNC"],
                                      config divider next sync only open or not.
            div_sync_en:      string, ["SYNC_OPEN", "SYNC_CLOSE"],
                                      config divider sync open or not.

        Examples:
            ad9628.clock_divide("BY_1", "NEX_SYNC", "SYNC_OPEN")

        '''
        assert divide_ratio in AD9628Def.CLOCK_DIVIDE
        assert div_next_sync in ["NEX_SYNC", "NEX_ASYNC"]
        assert div_sync_en in ["SYNC_OPEN", "SYNC_CLOSE"]

        divider_con = AD9628Def.CLOCK_DIVIDE[divide_ratio]
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["clock_divide"], divider_con)

        if div_next_sync == "NEX_SYNC":
            if div_sync_en == "SYNC_OPEN":
                sync_con = (AD9628Def.DIV_NEX_SYNC | AD9628Def.DIV_SYNC_OPEN)
            else:
                sync_con = (AD9628Def.DIV_NEX_SYNC | AD9628Def.DIV_SYNC_CLOSE)
        else:
            if div_sync_en == "SYNC_OPEN":
                sync_con = (AD9628Def.DIV_NEX_ASYNC | AD9628Def.DIV_SYNC_OPEN)
            else:
                sync_con = (AD9628Def.DIV_NEX_ASYNC | AD9628Def.DIV_SYNC_CLOSE)
        self.write_register(AD9628Def.REGISTER_ADDRESS["sync_ctrl"], sync_con)

    def clock_stabilizer(self, statu):
        '''
        AD9628 internal function to global clock duty cycle stabilizer control.

        Args:
            statu:    string, ["DIS_STABILIZE"/"EN_STABILIZE"],
                              control clock duty cycle stabilizer open or not.

        Examples:
            ad9628.clock_stabilizer("EN_STABILIZE")

        '''
        assert statu in ["DIS_STABILIZE", "EN_STABILIZE"]

        if statu == "EN_STABILIZE":
            stabilizer_con = 0x01
        else:
            stabilizer_con = 0x00
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["global_clock"], stabilizer_con)

    def cmos_output_adjust(self, dco_strength, data_strength):
        '''
        AD9628 internal function to config CMOS output driver strength properties.

        Args:
            dco_strength:     string, ["1X", "2X", "3X", "4X"],
                                      config DCO strength level when chip config in CMOS mode.
            data_strength:    string, ["1X", "2X", "3X", "4X"],
                                      config data strength level when chip config in CMOS mode.

        Examples:
            ad9628.cmos_output_adjust("1X", "1X")

        '''
        assert dco_strength in AD9628Def.DCO_STRENGTH
        assert data_strength in AD9628Def.DATA_STRENGTH

        cmos_adjust = AD9628Def.DCO_STRENGTH[dco_strength] | AD9628Def.DATA_STRENGTH[data_strength]
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["output_adjust"], cmos_adjust)

    def data_output_delay(self, dco_delay_en, data_delay_en, delay):
        '''
        AD9628 internal function to sets the fines output delay of the output clock, not change the internal timeing.

        Args:
            dco_delay_en:     string, ["DCO_DELAY_OPEN", "DCO_DELAY_CLOSE"],
                                      control DCO delay function open or not.
            data_delay_en:    string, ["DATA_DELAY_OPEN", "DATA_DELAY_CLOSE"],
                                      control data delay function open or not.
            delay:            string, ["0_56_NS", "1_12_NS", "1_68_NS", "2_24_NS",
                                       "2_80_NS", "3_36_NS", "3_92_NS", "4_48_NS"], select data delay level.

        Examples:
            ad9628.data_output_delay("DCO_DELAY_OPEN", "DATA_DELAY_OPEN", "1_12_NS")

        '''
        assert delay in AD9628Def.DATA_OUTPUT_DELAY
        assert dco_delay_en in ["DCO_DELAY_OPEN", "DCO_DELAY_CLOSE"]
        assert data_delay_en in ["DATA_DELAY_OPEN", "DATA_DELAY_CLOSE"]

        output_delay = AD9628Def.DATA_OUTPUT_DELAY[delay]
        if dco_delay_en == "DCO_DELAY_OPEN":
            if data_delay_en == "DATA_DELAY_OPEN":
                output_delay = (AD9628Def.DCO_DELAY_OPEN | AD9628Def.DATA_DELAY_OPEN | (output_delay))
            else:
                output_delay = (AD9628Def.DCO_DELAY_OPEN | AD9628Def.DATA_DELAY_CLOSE | (output_delay))
        else:
            if data_delay_en == "DATA_DELAY_OPEN":
                output_delay = (AD9628Def.DCO_DELAY_CLOSE | AD9628Def.DATA_DELAY_OPEN | (output_delay))
            else:
                output_delay = (AD9628Def.DCO_DELAY_CLOSE | AD9628Def.DATA_DELAY_CLOSE | (output_delay))

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["output_delay"], output_delay)

    def vref_set(self, vref, overrange_en):
        '''
        AD9628 internal function to adjuse AD9628 VREF level.

        Args:
            vref:            string, ["1_00", "1_14", "1_33", "1_60", "2_00"], config the inter VREF level.
            overrange_en:    string, ["OVERRANGE", "NOT_OVERRANGE"],  config output overrange enable or not.

        Examples:
            ad9628.vref_set("1_00", "OVERRANGE")

        '''
        assert vref in AD9628Def.VREF_LEVEL
        assert overrange_en in ["OVERRANGE", "NOT_OVERRANGE"]

        overrange_con = 0x01
        if overrange_en == "OVERRANGE":
            overrange_con = 0x01
        else:
            overrange_con = 0x00
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["overrange_reg"], overrange_con)

        vref_con = AD9628Def.VREF_LEVEL[vref]
        self.write_register(AD9628Def.REGISTER_ADDRESS["vref_reg"], vref_con)

    def _internal_power_mode(self, work_mode):
        '''
        AD9628 internal function to config AD9628 internal power mode.

        Args:
            work_mode:    string, ["POWER_ON", "POWER_DOWN", "STANDBY", "DIGITAL_RESET"],
                                  select AD9628's work mode.

        Examples:
            ad9628._internal_power_mode("POWER_ON")

        '''
        assert work_mode in AD9628Def.POWER_MODE

        power_con = 0
        power_con = self.read_register(
            AD9628Def.REGISTER_ADDRESS["power_mode"])
        power_con = ((power_con) & 0xFC) | AD9628Def.POWER_MODE[work_mode]

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["power_mode"], power_con)

    def _external_power_mode(self, work_mode):
        '''
        AD9628 internal function to config AD9628 external power mode.

        Args:
            work_mode:    string, ["POWER_ON", "POWER_DOWN"], select AD9628's work mode.

        Examples:
            ad9628._external_power_mode("POWER_ON")

        '''
        assert work_mode in ["POWER_ON", "POWER_DOWN"]

        if self.pdwn is None:
            raise AD9628RException('power mode set fail!')

        if work_mode == "POWER_ON":
            self.pdwn.set_level(1)
        else:
            self.pdwn.set_level(0)

    def power_mode(self, refer, work_mode):
        '''
        AD9628 internal function to config AD9628 chip power mode.

        Args:
            refer:        string, ["INTERNAL", "EXTERNAL"], select internal or external power mode for controling.
            work_mode:    string, ["POWER_ON", "POWER_DOWN", "STANDBY", "DIGITAL_RESET"],
                                  select AD9628's work mode.

        Examples:
            ad9628.power_mode("EXTERNAL", "POWER_ON")

        '''
        assert refer in ["INTERNAL", "EXTERNAL"]

        if refer == "INTERNAL":
            self._internal_power_mode(work_mode)
        else:
            self._external_power_mode(work_mode)

    def soft_reset(self):
        '''
        AD9628 internal function to AD9628 soft reset.

        Examples:
            ad9628.soft_reset()

        '''
        port_con = self.read_register(
            AD9628Def.REGISTER_ADDRESS["port_config"])
        port_con = ((port_con) | AD9628Def.SOFT_RESET)
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["port_config"], port_con)

    def chop_mode_open(self):
        '''
        AD9628 internal function to AD9628 enhancement control enable.

        Examples:
            ad9628.chop_mode_open()

        '''
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["enhancement_ctrl"], AD9628Def.CHOP_MODE_OPEN)

    def chop_mode_close(self):
        '''
        AD9628 internal function to AD9628 enhancement control disable.

        Examples:
            ad9628.chop_mode_close()

        '''
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["enhancement_ctrl"], AD9628Def.CHOP_MODE_CLOSE)

    def test_mode_config(self, user_mode, rst_pn_l_en, rst_pn_s_en, output_mode):
        '''
        AD9628 internal function to Config test data to AD9628's data output pins.

        Args:
            user_mode:      string, ["SINGLE", "ALTERNATE_REPEAT", "ONCE", "ALTERNATE_ONCE"],
                                    select user test mode.
            rst_pn_l_en:    string, ["EN_RESET_L", "DIS_RESET_L"],
                                    control reset PN long gen enable or not.
            rst_pn_s_en:    string, ["EN_RESET_S", "DIS_RESET_S"],
                                    control reset PN short gen enable or not.
            output_mode:    string, ["OFF", "MIDSCALE_SHORT", "POSITIVE_FS", "NEGATIVE_FS",
                                     "ALTERNATING_CHECKERBOARD", "PN_LONG_SEQUENCE", "PN_SHORT_SEQUENCE",
                                     "ONE_WORD_TOGGLE", "USER_TEST_MODE", "RAMP_OUTPUT"],
                                    select user output mode.

        Examples:
            ad9628.test_mode_config("SINGLE", "EN_RESET_L", "EN_RESET_S", "OFF")

        '''
        assert rst_pn_l_en in ["EN_RESET_L", "DIS_RESET_L"]
        assert rst_pn_s_en in ["EN_RESET_S", "DIS_RESET_S"]
        assert user_mode in AD9628Def.TEST_MODE
        assert output_mode in AD9628Def.OUTPUT_TEST_MODE

        user_test_mode_con = AD9628Def.TEST_MODE[user_mode]
        output_test_mode_con = AD9628Def.OUTPUT_TEST_MODE[output_mode]
        test_mode_con = (user_test_mode_con | AD9628Def.DIS_RESET_PN_LONG_GEN |
                         AD9628Def.DIS_RESET_PN_SHORT_GEN | output_test_mode_con)

        if rst_pn_l_en == "EN_RESET_L":
            if rst_pn_s_en == "EN_RESET_S":
                test_mode_con = (user_test_mode_con | AD9628Def.EN_RESET_PN_LONG_GEN | (
                                 AD9628Def.EN_RESET_PN_SHORT_GEN) | output_test_mode_con)
            else:
                test_mode_con = (user_test_mode_con | AD9628Def.EN_RESET_PN_LONG_GEN | (
                                 AD9628Def.DIS_RESET_PN_SHORT_GEN) | output_test_mode_con)
        else:
            if rst_pn_s_en == "EN_RESET_S":
                test_mode_con = ((user_test_mode_con) | AD9628Def.DIS_RESET_PN_LONG_GEN | (
                                 AD9628Def.EN_RESET_PN_SHORT_GEN) | (output_test_mode_con))
            else:
                test_mode_con = ((user_test_mode_con) | AD9628Def.DIS_RESET_PN_LONG_GEN | (
                                 AD9628Def.DIS_RESET_PN_SHORT_GEN) | (output_test_mode_con))

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["test_mode"], test_mode_con)

    def bist_mode_open(self, init_sequence):
        '''
        AD9628 internal function to BIST(build in self test) mode open.

        Args:
            init_sequence:    string, ["INIT_SEQ", "NOT_INIT_SEQ"],
                                      init sequence or not in BIST(build in self test) mode.

        Examples:
            ad9628.bist_mode_open("INIT_SEQ")

        '''
        assert init_sequence in ["INIT_SEQ", "NOT_INIT_SEQ"]

        bist_mode_con = AD9628Def.INIT_BIST_SEQ
        if init_sequence == "INIT_SEQ":
            bist_mode_con = AD9628Def.INIT_BIST_SEQ
        else:
            bist_mode_con = AD9628Def.NOT_INIT_BIST_SEQ

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["bist_reg"], bist_mode_con)

    def bist_mode_close(self):
        '''
        AD9628 internal function to BIST(build in self test) mode close.

        Examples:
            ad9628.bist_mode_close()

        '''
        self.write_register(
            AD9628Def.REGISTER_ADDRESS["bist_reg"], 0X00)

    def customer_offset_adjust(self, data):
        '''
        AD9628 internal function to Customer offset adjust when AD9628 config in twos complement format output type.

        Args:
            data:    hexmial, [0x00~0xFF], write register value.

        Examples:
            ad9628.customer_offset_adjust(0x00)

        '''
        assert isinstance(data, int)
        assert 0 <= data <= 0xFF

        self.write_register(
            AD9628Def.REGISTER_ADDRESS["customer_offset"], data)

    def user_define_pattern(self, pattern, format_data):
        '''
        AD9628 internal function to AD9628 user pattern definetion config.

        Args:
            pattern:        string, ["PATTERN_1", "PATTERN_2"], select which pattern to control.
            format_data:    hexmial, [0x00~0xFFFF], write register value.

        Examples:
            ad9628.user_define_pattern("PATTERN_1", 0x01)

        '''
        assert isinstance(format_data, int)
        assert pattern in ["PATTERN_1", "PATTERN_2"]
        assert 0x00 <= format_data <= 0xFFFF

        if pattern == "PATTERN_1":
            reg_address = AD9628Def.REGISTER_ADDRESS["user_pattern_1_L"] & 0x3FF
        else:
            reg_address = AD9628Def.REGISTER_ADDRESS["user_pattern_2_L"] & 0x3FF

        write_date = []
        write_date.append((reg_address & 0xFF00) >> 8)
        write_date.append(reg_address & 0x00FF)
        write_date.append(format_data >> 8 & 0xFF)
        write_date.append(format_data & 0xFF)
        self.spi_bus.write(write_date)

    def user_io_ctrl(self, io, state):
        '''
        AD9628 internal function to multiplexing pins control.

        Args:
            io:       string, ["OEB", "PDWN", "VCM", "SDIO"], select which IO to control.
            state:    string, ["EN_PIN", "DIS_PIN"],
                              control pin's function disable(effective when pin is PDWN) or enable.

        Examples:
            ad9628.user_io_ctrl("OEB", "EN_PIN")

        '''
        assert io in ["OEB", "PDWN", "VCM", "SDIO"]
        assert state in ["EN_PIN", "DIS_PIN"]

        if io == "OEB":
            rd_data = self.read_register(
                AD9628Def.REGISTER_ADDRESS["user_ctrl_reg_2"])
            if state == "EN_PIN":
                wr_data = (rd_data & 0x7F | AD9628Def.EN_OEB_PIN)
            else:
                wr_data = (rd_data & 0x7F | AD9628Def.DIS_OEB_PIN)
            return self.write_register(
                AD9628Def.REGISTER_ADDRESS["user_ctrl_reg_2"], wr_data)
        elif io == "PDWN":
            rd_data = self.read_register(
                AD9628Def.REGISTER_ADDRESS["power_mode"])
            if state == "EN_PIN":
                wr_data = (rd_data & 0xDF | AD9628Def.EN_PDWN_PIN)
            else:
                wr_data = (rd_data & 0xDF | AD9628Def.DIS_PDWN_PIN)
            return self.write_register(
                AD9628Def.REGISTER_ADDRESS["power_mode"], wr_data)
        elif io == "VCM":
            if state == "EN_PIN":
                wr_data = AD9628Def.VCM_POWER_ON
            else:
                wr_data = AD9628Def.VCM_POWER_DOWN
            return self.write_register(
                AD9628Def.REGISTER_ADDRESS["user_ctrl_reg_3"], wr_data)
        elif io == "SDIO":
            rd_data = self.read_register(
                AD9628Def.REGISTER_ADDRESS["user_ctrl_reg_2"])
            if state == "EN_PIN":
                wr_data = (rd_data & 0xFE | 1)
            else:
                wr_data = (rd_data & 0xFE | 0)
            return self.write_register(
                AD9628Def.REGISTER_ADDRESS["user_ctrl_reg_2"], wr_data)
Exemple #30
0
    def __init__(self,
                 i2c,
                 adc_rst_pin=None,
                 i2s_rx_en_pin=None,
                 dac_rst_pin=None,
                 i2s_tx_en_pin=None,
                 sample_rate=192000,
                 ipcore=None):
        assert sample_rate > 0 and sample_rate <= DazzlerDef.MAX_SAMPLING_RATE
        if i2c is None:
            self.eeprom = EepromEmulator("cat24cxx_emulator")
            self.nct75 = NCT75Emulator("nct75_emulator")
        else:
            self.eeprom = CAT24C32(DazzlerDef.EEPROM_I2C_ADDR, i2c)
            self.nct75 = NCT75(DazzlerDef.SENSOR_I2C_ADDR, i2c)

        MIXBoard.__init__(self,
                          self.eeprom,
                          self.nct75,
                          cal_table=dazzler_calibration_info,
                          range_table=dazzler_range_table)

        if ipcore:
            if isinstance(ipcore, basestring):
                axi4 = AXI4LiteBus(ipcore, DazzlerDef.MIX_AUT1_REG_SIZE)
                self.ip = MIXAUT1SGR(axi4)
            else:
                self.ip = ipcore
            self.analyzer = self.ip.analyzer
            self.signal_source = self.ip.signal_source
            self.adc_rst_pin = adc_rst_pin or Pin(self.ip.gpio,
                                                  DazzlerDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = i2s_rx_en_pin or Pin(self.ip.gpio,
                                                      DazzlerDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = dac_rst_pin or Pin(self.ip.gpio,
                                                  DazzlerDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = i2s_tx_en_pin or Pin(self.ip.gpio,
                                                      DazzlerDef.I2S_TX_EN_PIN)
        elif (not ipcore and not adc_rst_pin and not i2s_rx_en_pin
              and not dac_rst_pin and not i2s_tx_en_pin):
            self.analyzer = MIXFftAnalyzerSGEmulator(
                "mix_fftanalyzer_sg_emulator")
            self.signal_source = MIXSignalSourceSGEmulator(
                "mix_signalsource_sg_emulator")
            self.adc_rst_pin = Pin(None, DazzlerDef.ADC_RESET_PIN)
            self.i2s_rx_en_pin = Pin(None, DazzlerDef.I2S_RX_EN_PIN)
            self.dac_rst_pin = Pin(None, DazzlerDef.DAC_RESET_PIN)
            self.i2s_tx_en_pin = Pin(None, DazzlerDef.I2S_TX_EN_PIN)
        else:
            if ipcore:
                raise DazzlerException(
                    "parameter 'ipcore' can not be given at same time with 'analyzer', "
                    "'signal_source', 'adc_rst_pin', 'i2s_rx_en_pin', "
                    "'dac_rst_pin', 'i2s_tx_en_pin'")
            else:
                raise DazzlerException(
                    "parameter 'analyzer', 'signal_source', 'adc_rst_pin', "
                    "'i2s_rx_en_pin', 'dac_rst_pin' and 'i2s_tx_en_pin'"
                    " must be given at the same time")

        self.sample_rate = sample_rate