__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 TpmAdc9695(FirmwareBlock):
""" TpmAdc tests class """
@compatibleboards(BoardMake.Tpm16Board)
@friendlyname('tpm_adc')
@maxinstances(16)
def __init__(self, board, **kwargs):
""" TpmAdc initialiser
:param board: Pointer to board instance
"""
super(TpmAdc9695, self).__init__(board)
if 'adc_id' not in kwargs.keys():
raise PluginError("TpmAdc: adc_id required")
self._adc_id = kwargs['adc_id']
#######################################################################################
[docs]
def adc_single_start(self, mono_channel_14_bit=False, adc_test_pattern=0x0, mono_channel_sel=0):
""" Perform the ADC configuration and initialization procedure as implemented in ADI demo """
# JESD: 800 MSPS - 2 VCs - 2 lanes
# N'=8 n=8
# L = 2 M = 2 F = 1 S = 1 HD = 0
self.board[(self._adc_id, 0x0)] = 0x81 # reset
sleep(0.1)
self.board[(self._adc_id, 0x571)] = 0x15 # JESD Link mode Control 1 - restart
self.board[(self._adc_id, 0x3f)] = 0x80 # disable power down
self.board[(self._adc_id, 0x40)] = 0x00 # FD_A|B pins configured as Fast Detect outputs.
self.board[(self._adc_id, 0x120)] = 0xA # sysref
self.board[(self._adc_id, 0x200)] = 0x0
self.board[(self._adc_id, 0x201)] = 0x0
self.board[(self._adc_id, 0x550)] = adc_test_pattern # ADC test mode
# self.board[(self._adc_id, 0x573)] = 0x00 # test mode disable
self.board[(self._adc_id, 0x56E)] = 0x0 # Lane Rate
self.board[(self._adc_id, 0x572)] = 0x10 # SYNC CMOS level
self.board[(self._adc_id, 0x58b)] = 0x81 # JESD204B scrambler and lanes.
self.board[(self._adc_id, 0x58c)] = 0x0 # JESD204B number of octects (F)
self.board[(self._adc_id, 0x58d)] = 0x1f # JESD204B number of frame per multiframe (K)
if mono_channel_14_bit:
self.board[(self._adc_id, 0x58e)] = 0x0 # JESD204B number of converters (M)
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
if mono_channel_sel == 0:
logging.info("TpmAdc mono_channel_14_bit - selected channel A")
self.board[(self._adc_id, 0x564)] = 0 # Output channel select, Converter channel swap control
else:
logging.info("TpmAdc mono_channel_14_bit - selected channel B")
self.board[(self._adc_id, 0x564)] = 1 # Output channel select, Converter channel swap control
else:
self.board[(self._adc_id, 0x58e)] = 0x1 # JESD204B number of converters (M)
self.board[(self._adc_id, 0x58f)] = 0x7 # JESD204B number of control bits (CS) and ADC resolution (N)
self.board[(self._adc_id, 0x590)] = 0x27 # JESD204B Subclass and number of bits per sample (N')
self.board[(self._adc_id, 0x564)] = 0 # Output channel select, Converter channel swap control
if mono_channel_sel == 1:
logging.warning("TpmAdc mono_channel_sel ignored")
# pre-emphais test
# pre_emphasis = 0xc
# self.board[(self._adc_id, 0x5c4)] = pre_emphasis
# self.board[(self._adc_id, 0x5c6)] = pre_emphasis
# 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)] = 0x50 # xTPM unused lane power down
self.board[(self._adc_id, 0x571)] = 0x14
self.board[(self._adc_id, 0x1228)] = 0x4F # Reset JESD204B start-up circuit
self.board[(self._adc_id, 0x1228)] = 0x0F # JESD204B start-up circuit in normal operation
self.board[(self._adc_id, 0x1222)] = 0x00 # JESD204B PLL force normal operation
self.board[(self._adc_id, 0x1222)] = 0x04 # Reset JESD204B PLL calibration
self.board[(self._adc_id, 0x1222)] = 0x00 # JESD204B PLL normal operation
self.board[(self._adc_id, 0x1262)] = 0x08 # Clear loss of lock bit
self.board[(self._adc_id, 0x1262)] = 0x00 # Loss of lock bit normal operation
if do_until_eq(lambda: self.board[(self._adc_id, 0x56F)] == 0x80, 1, ms_retry=100, s_timeout=5) is None:
logging.warning("%s configuration failed" % self._adc_id)
else:
logging.debug("%s configuration OK" % self._adc_id)
[docs]
def adc_single_start_dual_14_ddc(self,
sampling_frequency=800e6,
ddc_frequency=100e6,
adc_test_pattern=0x0,
decimation_factor=0x8,
low_bitrate=0x1):
""" Perform the ADC configuration and initialization procedure as implemented in ADI demo """
# bitrate: JESD204B lane rate control
# 0011 => Lane rate = 13.5 Gbps to 16 Gbps.
# 0000 => Lane rate = 6.75 Gbps to 13.5 Gbps.
# 0001 => Lane rate = 3.375 Gbps to 6.75 Gbps.
# 0101 => Lane rate = 1.6875 Gbps to 3.375 Gbps.
self.board[(self._adc_id, 0x0)] = 0x81 # reset
sleep(0.1)
self.board[(self._adc_id, 0x571)] = 0x15 # JESD Link mode Control 1 - restart
self.board[(self._adc_id, 0x3f)] = 0x80 # disable power down
self.board[(self._adc_id, 0x40)] = 0x00 # FD_A|B pins configured as Fast Detect outputs.
self.board[(self._adc_id, 0x120)] = 0xA # sysref
self.board[(self._adc_id, 0x200)] = 0x0
self.board[(self._adc_id, 0x201)] = 0x0
self.board[(self._adc_id, 0x550)] = adc_test_pattern # ADC test mode
# self.board[(self._adc_id, 0x573)] = 0x00 # test mode disable
self.board[(self._adc_id, 0x56E)] = 0x0 # Lane Rate
self.board[(self._adc_id, 0x572)] = 0x10 # SYNC CMOS level
self.board[(self._adc_id, 0x58b)] = 0x80 # JESD204B scrambler and lanes. # L=1
self.board[(self._adc_id, 0x58c)] = 0x3 # JESD204B number of octects (F)
self.board[(self._adc_id, 0x58d)] = 0x1f # JESD204B number of frame per multiframe (K)
self.board[(self._adc_id, 0x58e)] = 0x1 # JESD204B number of converters (M)
self.board[(self._adc_id, 0x58f)] = 0xF # JESD204B number of control bits (CS) and ADC resolution (N)
self.board[(self._adc_id, 0x590)] = 0x2F # JESD204B Subclass and number of bits per sample (N')
self.board[(self._adc_id, 0x564)] = 0 # Output channel select, Converter channel swap control
# pre-emphais test
# pre_emphasis = 0xc
# self.board[(self._adc_id, 0x5c4)] = pre_emphasis
# self.board[(self._adc_id, 0x5c6)] = pre_emphasis
# 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)] = 0x50 # xTPM unused lane power down
# DDC configuration
nco_freq = int((ddc_frequency / sampling_frequency) * 2 ** 48)
if decimation_factor == 8:
self.board[(self._adc_id, 0x200)] = 0x22 # (two DDCs; I only selected)
self.board[(self._adc_id, 0x201)] = 0x03 # (chip decimate by 8)
# DDC0 and DDC1
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, 0x311)] = 0x00 # (DDC 0 I input = ADC Channel A; DDC 0 Q input = ADC Channel A)
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, 0x331)] = 0x05 # (DDC 1 I input = ADC Channel B; DDC 1 Q input = ADC Channel B)
elif decimation_factor == 20:
self.board[(self._adc_id, 0x200)] = 0x23 # (two DDCs; I only selected)
self.board[(self._adc_id, 0x201)] = 0x0D # (chip decimate by 20)
# DDC0 and DDC1
self.board[(self._adc_id, 0x310)] = 0x4F # (real mixer; 6 dB gain; variable IF; real output; filters selected by next register)
self.board[(self._adc_id, 0x311)] = 0x40 # (FB2 + HB3 + HB2 + HB1 filters; DDC 0 I input = ADC Channel A; DDC 0 Q input = ADC Channel A)
self.board[(self._adc_id, 0x330)] = 0x4F # (real mixer; 6 dB gain; variable IF; real output; filters selected by next register)
self.board[(self._adc_id, 0x331)] = 0x45 # (FB2 + HB3 + HB2 + HB1 filters; DDC 1 I input = ADC Channel B; DDC 1 Q input = ADC Channel B)
else:
raise PluginError("TpmAdc: not supported decimation factor " + str(decimation_factor))
for n in range(2):
self.board[(self._adc_id, 0x314 + 0x20 * n)] = 0 # DDC0 NCO control
self.board[(self._adc_id, 0x315 + 0x20 * n)] = 0 # DDC0 Phase control
for m in range(6):
self.board[(self._adc_id, 0x316 + 0x20 * n + m)] = (nco_freq >> (m * 8)) & 0xFF
for m in range(6):
self.board[(self._adc_id, 0x31D + 0x20 * n + m)] = 0 # phase offset
if type(low_bitrate) == bool:
if low_bitrate:
self.board[(self._adc_id, 0x56e)] = 0x10 # JESD line rate < 6.25 Gbps
else:
self.board[(self._adc_id, 0x56e)] = 0x0 # JESD 6.25 Gbps < line rate < 13.5 Bbps
elif type(low_bitrate) == int:
self.board[(self._adc_id, 0x56e)] = low_bitrate << 4
self.board[(self._adc_id, 0x571)] = 0x14
self.board[(self._adc_id, 0x1228)] = 0x4F # Reset JESD204B start-up circuit
self.board[(self._adc_id, 0x1228)] = 0x0F # JESD204B start-up circuit in normal operation
self.board[(self._adc_id, 0x1222)] = 0x00 # JESD204B PLL force normal operation
self.board[(self._adc_id, 0x1222)] = 0x04 # Reset JESD204B PLL calibration
self.board[(self._adc_id, 0x1222)] = 0x00 # JESD204B PLL normal operation
self.board[(self._adc_id, 0x1262)] = 0x08 # Clear loss of lock bit
self.board[(self._adc_id, 0x1262)] = 0x00 # Loss of lock bit normal operation
if do_until_eq(lambda: self.board[(self._adc_id, 0x56F)] == 0x80, 1, ms_retry=100, s_timeout=5) is None:
logging.warning("%s configuration failed" % self._adc_id)
else:
logging.debug("%s configuration OK" % self._adc_id)
[docs]
def adc_set_fast_detect(self, upper_threshold, lower_threshold=None, dwell_samples=100):
if lower_threshold is 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
# ##################### 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