Source code for pyfabil.plugins.tpm.adc

from __future__ import division
__author__ = 'lessju'

from pyfabil.plugins.firmwareblock import FirmwareBlock
from pyfabil.base.definitions import *
from pyfabil.base.utils import *
from time import sleep
import logging


[docs] class TpmAdc(FirmwareBlock): """ TpmAdc tests class """ @compatibleboards(BoardMake.TpmBoard) @friendlyname('tpm_adc') @maxinstances(16) def __init__(self, board, **kwargs): """ TpmAdc initialiser :param board: Pointer to board instance """ super(TpmAdc, self).__init__(board) if 'adc_id' not in list(kwargs.keys()): raise PluginError("TpmAdc: adc_id required") self._adc_id = kwargs['adc_id'] #######################################################################################
[docs] def adc_reset(self): self.board[(self._adc_id, 0x0)] = 0x81 time.sleep(0.01) # soft reset requires 5ms, see AD9680 datasheet
[docs] def adc_power_down_enable(self): self.board[(self._adc_id, 0x3F)] = 0x0 self.board[(self._adc_id, 0x40)] = 0x0
[docs] def adc_power_down_disable(self): self.board[(self._adc_id, 0x3F)] = 0x80 self.board[(self._adc_id, 0x40)] = 0x80 sleep(0.01) # exit from power-down requires 4ms, see AD9680 datasheet
[docs] def adc_single_start(self, mono_channel_14_bit=False, clock_divider=1, low_bitrate=False, mono_channel_sel=1): """ Perform the ADC configuration and initialization procedure as implemented in ADI demo """ self.adc_power_down_disable() self.board[(self._adc_id, 0x18)] = 0x40 # Input buffer current 3.0X self.board[(self._adc_id, 0x120)] = 0xA # sysref, falling edge self.board[(self._adc_id, 0x550)] = 0x0 # ADC test mode self.board[(self._adc_id, 0x573)] = 0x00 # test mode disable if clock_divider != 1: if clock_divider in [2, 4, 8]: self.board[(self._adc_id, 0x10b)] = clock_divider-1 self.board[(self._adc_id, 0x10d)] = 0x80 else: raise PluginError("TpmAdc: ADC clock divider %d is not supported" % clock_divider) self.board[(self._adc_id, 0x571)] = 0x15 # JESD Link mode Control 1 self.board[(self._adc_id, 0x572)] = 0x10 # SYNC CMOS level self.board[(self._adc_id, 0x58b)] = 0x81 # JESD204B scrambler and lanes. lanes are read only here self.board[(self._adc_id, 0x58d)] = 0x1f # number of frame per multiframe if mono_channel_14_bit: self.board[(self._adc_id, 0x58f)] = 0xF # JESD204B CS/N config self.board[(self._adc_id, 0x590)] = 0x2F # JESD204B subclass and number of bits #X self.board[(self._adc_id, 0x570)] = 0x40 # JESD204B quick configuration # Input swap if mono_channel_sel == 0: self.board[(self._adc_id, 0x564)] = 0x0 else: self.board[(self._adc_id, 0x564)] = 0x1 else: self.board[(self._adc_id, 0x58f)] = 0x7 # JESD204B CS/N config self.board[(self._adc_id, 0x590)] = 0x27 # JESD204B subclass and number of bits #X self.board[(self._adc_id, 0x570)] = 0x48 # JESD204B quick configuration # Lane remap self.board[(self._adc_id, 0x5b2)] = 0x00 self.board[(self._adc_id, 0x5b3)] = 0x01 self.board[(self._adc_id, 0x5b5)] = 0x00 self.board[(self._adc_id, 0x5b6)] = 0x01 self.board[(self._adc_id, 0x5b0)] = 0xFA # xTPM unused lane power down if low_bitrate: self.board[(self._adc_id, 0x56e)] = 0x10 # JESD line rate < 6.25 Gbps self.board[(self._adc_id, 0x571)] = 0x14 if do_until_eq(lambda: self.board[(self._adc_id, 0x56F)] == 0x80, 1, ms_retry=100, s_timeout=10) is None: raise PluginError("ADC configuration failed, " + str(self._adc_id).upper() + " PLL not locked") if self.board[(self._adc_id, 0x58b)] != 0x81: # jesd lane number raise PluginError("TpmAdc: Number of lane is not correct") if self.board[(self._adc_id, 0x58c)] != 0: # octets per frame raise PluginError("TpmAdc: Number of octets per frame is not correct") if self.board[(self._adc_id, 0x58d)] != 0x1f: # frames per multiframe raise PluginError("TpmAdc: Number of frame per multiframe is not correct") if self.board[(self._adc_id, 0x58e)] != 1 and not mono_channel_14_bit: # virtual converters raise PluginError("TpmAdc: Number of virtual converters is not correct") if self.board[(self._adc_id, 0x58e)] != 0 and mono_channel_14_bit: # virtual converters raise PluginError("TpmAdc: Number of virtual converters is not correct")
[docs] def adc_single_start_dual_14_ddc(self, sampling_frequency=800e6, ddc_frequency=100e6, low_bitrate=False): """ Perform the ADC configuration and initialization procedure as implemented in ADI demo """ self.adc_power_down_disable() self.board[(self._adc_id, 0x18)] = 0x40 # Input buffer current 3.0X self.board[(self._adc_id, 0x120)] = 0xA # sysref, falling edge self.board[(self._adc_id, 0x550)] = 0x0 # ADC test mode self.board[(self._adc_id, 0x573)] = 0x00 # test mode disable self.board[(self._adc_id, 0x571)] = 0x15 # JESD Link mode Control 1, power-down self.board[(self._adc_id, 0x572)] = 0x10 # SYNC CMOS level self.board[(self._adc_id, 0x58b)] = 0x80 # JESD204B scrambler and lanes. lanes are read only here self.board[(self._adc_id, 0x58d)] = 0x1f # number of frame per multiframe self.board[(self._adc_id, 0x58f)] = 0x0F # JESD204B CS/N config self.board[(self._adc_id, 0x590)] = 0x2F # JESD204B subclass and number of bits #X self.board[(self._adc_id, 0x570)] = 0x0A # JESD204B quick configuration # Lane remap self.board[(self._adc_id, 0x5b2)] = 0x00 self.board[(self._adc_id, 0x5b3)] = 0x00 self.board[(self._adc_id, 0x5b5)] = 0x00 self.board[(self._adc_id, 0x5b6)] = 0x00 self.board[(self._adc_id, 0x5b0)] = 0xFA # xTPM unused lane power down # DDC configuration self.board[(self._adc_id, 0x200)] = 0x22 # (two DDCs; I only selected) self.board[(self._adc_id, 0x201)] = 0x03 # (chip decimate by 8) self.board[(self._adc_id, 0x310)] = 0x4A # (real mixer; 6 dB gain; variable IF; real output; HB4 + HB3 + HB2 + HB1 filters) self.board[(self._adc_id, 0x330)] = 0x4A # (real mixer; 6 dB gain; variable IF; real output; HB4 + HB3 + HB2 + HB1 filters) self.board[(self._adc_id, 0x311)] = 0x00 # (DDC 0 I input = ADC Channel A; DDC 0 Q input = ADC Channel A) self.board[(self._adc_id, 0x331)] = 0x05 # (DDC 1 I input = ADC Channel B; DDC 1 Q input = ADC Channel B) nco_freq = int((ddc_frequency / sampling_frequency) * 4096) self.board[(self._adc_id, 0x314)] = nco_freq & 0xFF self.board[(self._adc_id, 0x315)] = nco_freq >> 8 self.board[(self._adc_id, 0x334)] = nco_freq & 0xFF self.board[(self._adc_id, 0x335)] = nco_freq >> 8 self.board[(self._adc_id, 0x320)] = 0 self.board[(self._adc_id, 0x321)] = 0 self.board[(self._adc_id, 0x340)] = 0 self.board[(self._adc_id, 0x341)] = 0 if low_bitrate: self.board[(self._adc_id, 0x56e)] = 0x10 # JESD line rate < 6.25 Gbps self.board[(self._adc_id, 0x571)] = 0x14 # JESD Link mode Control 1, power-up if do_until_eq(lambda: self.board[(self._adc_id, 0x56F)] == 0x80, 1, ms_retry=100, s_timeout=10) is None: raise PluginError("ADC configuration failed, ADC" + str(self._adc_id) + " PLL not locked") if self.board[(self._adc_id, 0x58b)] != 0x80: # jesd lane number raise PluginError("TpmAdc: Number of lane is not correct") if self.board[(self._adc_id, 0x58c)] != 3: # octets per frame raise PluginError("TpmAdc: Number of octets per frame is not correct") if self.board[(self._adc_id, 0x58d)] != 0x1f: # frames per multiframe raise PluginError("TpmAdc: Number of frame per multiframe is not correct") if self.board[(self._adc_id, 0x58e)] != 1: # virtual converters raise PluginError("TpmAdc: Number of virtual converters is not correct")
[docs] def adc_single_start_dual_14_divider(self, clock_divider=2, low_bitrate=False): """ Perform the ADC configuration and initialization procedure as implemented in ADI demo """ self.adc_power_down_disable() self.board[(self._adc_id, 0x18)] = 0x40 # Input buffer current 3.0X self.board[(self._adc_id, 0x120)] = 0xA # sysref, falling edge self.board[(self._adc_id, 0x550)] = 0x0 # ADC test mode self.board[(self._adc_id, 0x573)] = 0x00 # test mode disable if clock_divider in [1, 2, 4, 8]: self.board[(self._adc_id, 0x10b)] = clock_divider-1 self.board[(self._adc_id, 0x10d)] = 0x80 else: raise PluginError("TpmAdc: ADC clock divider %d is not supported" % clock_divider) self.board[(self._adc_id, 0x571)] = 0x15 # JESD Link mode Control 1, power-down self.board[(self._adc_id, 0x572)] = 0x10 # SYNC CMOS level self.board[(self._adc_id, 0x58b)] = 0x80 # JESD204B scrambler and lanes. lanes are read only here self.board[(self._adc_id, 0x58d)] = 0x1f # number of frame per multiframe self.board[(self._adc_id, 0x58f)] = 0x0F # JESD204B CS/N config self.board[(self._adc_id, 0x590)] = 0x2F # JESD204B subclass and number of bits #X self.board[(self._adc_id, 0x570)] = 0x49 # JESD204B quick configuration # Lane remap self.board[(self._adc_id, 0x5b2)] = 0x00 self.board[(self._adc_id, 0x5b3)] = 0x01 self.board[(self._adc_id, 0x5b5)] = 0x00 self.board[(self._adc_id, 0x5b6)] = 0x01 self.board[(self._adc_id, 0x5b0)] = 0xFA # xTPM unused lane power down # if low_bitrate: # self.board[(self._adc_id, 0x56e)] = 0x10 # JESD line rate < 6.25 Gbps self.board[(self._adc_id, 0x571)] = 0x14 # JESD Link mode Control 1, power-up if do_until_eq(lambda: self.board[(self._adc_id, 0x56F)] == 0x80, 1, ms_retry=100, s_timeout=10) is None: raise PluginError("ADC configuration failed, ADC" + str(self._adc_id) + " PLL not locked") if self.board[(self._adc_id, 0x58b)] != 0x81: # jesd lane number raise PluginError("TpmAdc: Number of lane is not correct") if self.board[(self._adc_id, 0x58c)] != 1: # octets per frame raise PluginError("TpmAdc: Number of octets per frame is not correct") if self.board[(self._adc_id, 0x58d)] != 0x1f: # frames per multiframe raise PluginError("TpmAdc: Number of frame per multiframe is not correct") if self.board[(self._adc_id, 0x58e)] != 1: # virtual converters raise PluginError("TpmAdc: Number of virtual converters is not correct")
[docs] def adc_set_fast_detect(self, upper_threshold, lower_threshold=None, dwell_samples=100): if lower_threshold == None: lower_threshold = upper_threshold rd = self.board[(self._adc_id, 0x040)] self.board[(self._adc_id, 0x040)] = rd & 0xC0 self.board[(self._adc_id, 0x247)] = upper_threshold & 0xFF #Upper Threshold LSB self.board[(self._adc_id, 0x248)] = (upper_threshold >> 8) & 0xFF #Upper Threshold MSB self.board[(self._adc_id, 0x249)] = lower_threshold & 0xFF #Lower Threshold LSB self.board[(self._adc_id, 0x24A)] = (lower_threshold >> 8) & 0xFF #Lower Threshold MSB self.board[(self._adc_id, 0x24B)] = dwell_samples & 0xFF #Dwell Time LSB self.board[(self._adc_id, 0x24C)] = (dwell_samples >> 8) & 0xFF #Dwell Time MSB self.board[(self._adc_id, 0x245)] = 0x1 # Enable Fast Detect ADC outputs
[docs] def adc_test_pattern_enable(self, pattern_type=0xF): self.board[(self._adc_id, 0x550)] = pattern_type
[docs] def adc_test_pattern_disable(self): self.board[(self._adc_id, 0x550)] = 0x0
##################### Superclass method implementations #################################
[docs] def initialise(self): """ Initialise TpmPll """ logging.info("TpmAdc has been initialised") return True
[docs] def status_check(self): """ Perform status check :return: Status """ logging.info("TpmAdc : Checking status") return Status.OK
[docs] def clean_up(self): """ Perform cleanup :return: Success """ logging.info("TpmAdc : Cleaning up") return True