Commit 5aae3b2f authored by Matthieu Cattin's avatar Matthieu Cattin

tmp: Working on fmc_adc module.

Adding exception handling, updating interfaces to common modules.
parent e35d919e
#! /usr/bin/env python
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2012
# Author: Matthieu Cattin (CERN)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 8/5/2012
# Import standard modules
import sys
import rr
import random
import time
import spi
import ltc217x
import csr
import max5442
import i2c
import onewire
import ds18b20
#import mcp9801
import si57x
import eeprom_24aa64
import random
import math
import random
# Import specific modules
#import rr
from csr import *
from onewire import *
from i2c import *
from spi import *
from ds18b20 import *
from eeprom_24aa64 import *
from ltc217x import *
from max5442 import *
from si57x import *
# Import register maps
from fmcadc100m_csr import *
# Converts digital value to volts
......@@ -47,8 +65,15 @@ def signed2hex(value):
return value
# Class to access fmcadc100m14b4cha mezzanine specific Wishbone cores
class CFmcAdc100Ms:
class FmcAdc100mOperationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return ("FmcAdc100m: %s" %(self.msg))
class CFmcAdc100m:
FMC_SYS_I2C_ADDR = 0x60000
EEPROM_ADDR = 0x50
......@@ -58,11 +83,14 @@ class CFmcAdc100Ms:
FMC_SPI_SS = {'ADC': 0,'DAC1': 1,'DAC2': 2,'DAC3': 3,'DAC4': 4}
FMC_I2C_ADDR = 0x80000
#MCP9801_ADDR = 0x48
SI570_ADDR = 0x55
FMC_ONEWIRE_ADDR = 0xA0000
FMC_CSR_ADDR = 0x90000
"""
FMC_CSR = {0x00:'Control register',
0x04:'Status register',
0x08:'Trigger configuration register',
......@@ -90,7 +118,7 @@ class CFmcAdc100Ms:
0x60:'CH4 current value register',
0x64:'CH4 gain calibration register',
0x68:'CH4 offset calibration register',}
FMC_CSR_ADDR = 0x90000
R_CTL = 0x00
R_STA = 0x04
R_TRIG_CFG = 0x08
......@@ -136,9 +164,12 @@ class CFmcAdc100Ms:
STA_SERDES_SYNCED = 4
FSM_MASK = 0x00000007
"""
FSM_STATES = ['N/A','IDLE','PRE_TRIG','WAIT_TRIG',
'POST_TRIG','DECR_SHOT','N/A','others']
"""
TRIG_CFG_HW_SEL = 0
TRIG_CFG_EXT_POL = 1
TRIG_CFG_HW_EN = 2
......@@ -148,6 +179,7 @@ class CFmcAdc100Ms:
INT_SEL_MASK = 0xFFFFFFCF
INT_THRES_MASK = 0x0000FFFF
"""
IN_TERM = (1<<3)
IN_TERM_MASK = 0x08
......@@ -161,7 +193,7 @@ class CFmcAdc100Ms:
def channel_addr(self, channel, reg):
if(channel < 1 or channel > 4):
raise Exception('Channel number not in range (1 to 4).')
raise FmcAdc100mOperationError("Channel number not in range (1 to 4).")
else:
addr = (reg + (0x10*(channel - 1)))
#print("Channel %d address: %.2X") % (channel, addr)
......@@ -169,33 +201,48 @@ class CFmcAdc100Ms:
def __init__(self, bus):
self.bus = bus
# Objects declaration
self.fmc_sys_i2c = i2c.COpenCoresI2C(self.bus, self.FMC_SYS_I2C_ADDR, 249)
self.eeprom_24aa64 = eeprom_24aa64.C24AA64(self.fmc_sys_i2c, self.EEPROM_ADDR)
self.fmc_spi = spi.COpenCoresSPI(self.bus, self.FMC_SPI_ADDR, self.FMC_SPI_DIV)
self.adc_cfg = ltc217x.CLTC217x(self.fmc_spi, self.FMC_SPI_SS['ADC'])
self.fmc_i2c = i2c.COpenCoresI2C(self.bus, self.FMC_I2C_ADDR, 249)
self.fmc_onewire = onewire.COpenCoresOneWire(self.bus, self.FMC_ONEWIRE_ADDR, 624, 124)
self.ds18b20 = ds18b20.CDS18B20(self.fmc_onewire, 0)
self.si570 = si57x.CSi57x(self.fmc_i2c, self.SI570_ADDR)
self.fmc_adc_csr = csr.CCSR(self.bus, self.FMC_CSR_ADDR)
self.dac_ch1 = max5442.CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC1'])
self.dac_ch2 = max5442.CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC2'])
self.dac_ch3 = max5442.CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC3'])
self.dac_ch4 = max5442.CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC4'])
# Set channels gaim to 1
self.fmc_adc_csr.wr_reg(self.R_CH1_GAIN, 0x8000)
self.fmc_adc_csr.wr_reg(self.R_CH2_GAIN, 0x8000)
self.fmc_adc_csr.wr_reg(self.R_CH3_GAIN, 0x8000)
self.fmc_adc_csr.wr_reg(self.R_CH4_GAIN, 0x8000)
try:
self.fmc_sys_i2c = COpenCoresI2C(self.bus, self.FMC_SYS_I2C_ADDR, 249)
self.fmc_i2c = COpenCoresI2C(self.bus, self.FMC_I2C_ADDR, 249)
except I2CDeviceOperationError as e:
raise FmcAdc100mOperationError(e)
self.eeprom_24aa64 = C24AA64(self.fmc_sys_i2c, self.EEPROM_ADDR)
self.si570 = CSi57x(self.fmc_i2c, self.SI570_ADDR)
self.fmc_onewire = COpenCoresOneWire(self.bus, self.FMC_ONEWIRE_ADDR, 624, 124)
self.ds18b20 = CDS18B20(self.fmc_onewire, 0)
self.fmc_adc_csr = CCSR(self.bus, self.FMC_CSR_ADDR, FMCADC100M_CSR)
self.fmc_spi = COpenCoresSPI(self.bus, self.FMC_SPI_ADDR, self.FMC_SPI_DIV)
self.adc_cfg = CLTC217x(self.fmc_spi, self.FMC_SPI_SS['ADC'])
self.dac_ch[1] = CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC1'])
self.dac_ch[2] = CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC2'])
self.dac_ch[3] = CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC3'])
self.dac_ch[4] = CMAX5442(self.fmc_spi, self.FMC_SPI_SS['DAC4'])
# Set channels gain to 1
self.fmc_adc_csr.set_field('CH1_GAIN', 'VAL', 0x8000)
self.fmc_adc_csr.set_field('CH2_GAIN', 'VAL', 0x8000)
self.fmc_adc_csr.set_field('CH3_GAIN', 'VAL', 0x8000)
self.fmc_adc_csr.set_field('CH4_GAIN', 'VAL', 0x8000)
# Enable mezzanine clock and offset DACs
self.fmc_adc_csr.wr_reg(self.R_CTL, ((1<<self.CTL_CLK_EN)|(1<<self.CTL_OFFSET_DAC_CLR_N)))
self.fmc_adc_csr.set_field('CTL', 'FMC_CLK_OE', 1)
self.fmc_adc_csr.set_field('CTL', 'OFFSET_DAC_CLR_N', 1)
# Disable ADC test pattern
self.adc_cfg.dis_testpat()
#def __del__(self):
# Disable ADC clock and reset offset correction DAC
#self.fmc_adc_csr.wr_reg(self.R_CTL, 0)
def channel_check(self, channel):
if(channel < 1 or channel > 4):
raise FmcAdc100mOperationError("Channel number %d, not in range 1 to 4.")
else:
return channel
# Front panel LED manual control
def acq_led(self, state):
......@@ -230,35 +277,48 @@ class CFmcAdc100Ms:
# print FMC unique ID
def print_unique_id(self):
print('FMC unique ID: %.12X') % self.ds18b20.read_serial_number()
try:
print('FMC unique ID: %.12X') % self.ds18b20.read_serial_number()
except DS18B20OperationError as e:
raise FmcAdc100mOperationError(e)
# print FMC temperature
def print_temp(self):
serial_number = self.ds18b20.read_serial_number()
print("FMC temperature: %3.3f°C") % self.ds18b20.read_temp(serial_number)
try:
serial_number = self.ds18b20.read_serial_number()
print("FMC temperature: %3.3f°C") % self.ds18b20.read_temp(serial_number)
except DS18B20OperationError as e:
raise FmcAdc100mOperationError(e)
# Returns FMC unique ID
def get_unique_id(self):
return self.ds18b20.read_serial_number()
try:
return self.ds18b20.read_serial_number()
except DS18B20OperationError as e:
raise FmcAdc100mOperationError(e)
# Returns FMC temperature
def get_temp(self):
serial_number = self.ds18b20.read_serial_number()
if(serial_number == -1):
return -1
else:
try:
serial_number = self.ds18b20.read_serial_number()
return self.ds18b20.read_temp(serial_number)
except DS18B20OperationError as e:
raise FmcAdc100mOperationError(e)
# scan FMC i2c bus
def i2c_scan(self):
print '\nScan I2C bus'
print '\nScanning FMC I2C bus'
return self.fmc_i2c.scan()
# scan FMC system i2c bus
def sys_i2c_scan(self):
print '\nScan system I2C bus'
print '\nScanning FMC system I2C bus'
return self.fmc_sys_i2c.scan()
###########################################################################
########## Code to review ##########
# write to EEPROM on system i2c bus
def sys_i2c_eeprom_write(self, addr, data):
return self.eeprom_24aa64.wr_data(addr, data)
......@@ -267,56 +327,52 @@ class CFmcAdc100Ms:
def sys_i2c_eeprom_read(self, addr, size):
return self.eeprom_24aa64.rd_data(addr, size)
###########################################################################
# Set input range
def set_input_range(self, channel, in_range):
addr = self.channel_addr(channel,self.R_CH1_SSR)
reg = (self.IN_TERM_MASK & self.fmc_adc_csr.rd_reg(addr))
#print("ssr reg ch%1d: %.8X") %(channel, reg)
#print('[set_in_range] Channel %d Input range: %s')%(channel,in_range)
if(in_range in self.IN_RANGES):
reg |= self.IN_RANGES[in_range]
else:
raise Exception('Unsupported parameter.')
#print("ssr reg ch%1d: %.8X") %(channel, reg)
self.fmc_adc_csr.wr_reg(addr, reg)
#print("ssr reg ch%1d: %.8X") %(channel, self.fmc_adc_csr.rd_reg(addr))
reg_name = 'CH'+str(self.channel_check(channel))+"_CTL"
try:
# read channel control register
reg_val = self.fmc_adc_csr.get_reg(reg_name)
# Save input termination bit state
reg_val = self.IN_TERM_MASK & reg_val
#print "[FmcAdc100m] ssr reg ch%1d: %.8X" % (channel, reg_val)
#print "[FmcAdc100m] Channel %d Input range: %s" % (channel,in_range)
if(in_range in self.IN_RANGES):
reg_val |= self.IN_RANGES[in_range]
else:
raise FmcAdc100mOperationError("Requested input range (%s) doesn\'t exist." % in_range)
#print "[FmcAdc100m] ssr reg ch%1d: %.8X" % (channel, reg_val)
self.fmc_adc_csr.set_reg(reg_name, reg_val)
#print "[FmcAdc100m] ssr reg ch%1d: %.8X" % (channel, self.fmc_adc_csr.get_reg(reg_name))
except CSRDeviceOperationError as e:
raise FmcAdc100mOperationError(e)
# Set SSR register
def set_ssr(self, channel, value):
addr = self.channel_addr(channel,self.R_CH1_SSR)
self.fmc_adc_csr.wr_reg(addr, value)
reg_name = 'CH'+str(self.channel_check(channel))+"_CTL"
try:
self.fmc_adc_csr.set_reg(reg_name, value)
except CSRDeviceOperationError as e:
raise FmcAdc100mOperationError(e)
# Get SSR register
def get_ssr(self, channel):
addr = self.channel_addr(channel,self.R_CH1_SSR)
return self.fmc_adc_csr.rd_reg(addr)
reg_name = 'CH'+str(self.channel_check(channel))+"_CTL"
try:
return self.fmc_adc_csr.get_reg(reg_name)
except CSRDeviceOperationError as e:
raise FmcAdc100mOperationError(e)
# DC offset calibration
def dc_offset_calibr(self, channel, offset):
if(1 == channel):
self.dac_ch1.set_offset(offset)
elif(2 == channel):
self.dac_ch2.set_offset(offset)
elif(3 == channel):
self.dac_ch3.set_offset(offset)
elif(4 == channel):
self.dac_ch4.set_offset(offset)
else:
raise Exception('Unsupported parameter, channel number from 1 to 4')
# Set DC offset
# Set channel DC offset (MAX5442 DAC)
def set_dc_offset(self, channel, offset):
if(1 == channel):
self.dac_ch1.set_offset(offset)
elif(2 == channel):
self.dac_ch2.set_offset(offset)
elif(3 == channel):
self.dac_ch3.set_offset(offset)
elif(4 == channel):
self.dac_ch4.set_offset(offset)
else:
raise Exception('Unsupported parameter, channel number from 1 to 4')
ch = self.channel_check(channel)
try:
self.dac_ch[ch].set_value(offset)
except MAX5442OperationError as e:
raise FmcAdc100mOperationError(e)
def set_dac_corr(self, corr_data):
self.dac_corr_data = corr_data
......
......@@ -5,7 +5,7 @@
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 7/5/2012
# Last modifications: 10/5/2012
# Import system modules
import sys
......@@ -38,8 +38,8 @@ def main (default_directory='.'):
start_test_time = time.time()
print "================================================================================"
print "Test00 start\n"
print "\n================================================================================"
print "==> Test00 start\n"
# SPEC object declaration
print "Loading hardware access library and opening device.\n"
......@@ -70,7 +70,7 @@ def main (default_directory='.'):
# Print carrier CSR registers
carrier.print_csr()
print "End of test00\n"
print "==> End of test00"
print "================================================================================"
end_test_time = time.time()
print "Test00 elapsed time: %.2f seconds\n" % (end_test_time-start_test_time)
......
......@@ -5,16 +5,25 @@
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 11/5/2012
# Import system modules
import sys
import rr
import time
import os
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
from ptsexcept import *
import rr
import csr
import fmc_adc
# Import specific modules
from fmc_adc_spec import *
from fmc_adc import *
"""
......@@ -23,46 +32,34 @@ test01: Test 1-wire thermometer and read the unique ID.
Note: Requires test00.py to run first to load the firmware!
"""
CARRIER_CSR = 0x30000
CSR_TYPE_VER = 0x00
CSR_BSTM_TYPE = 0x04
CSR_BSTM_DATE = 0x08
CSR_STATUS = 0x0C
CSR_CTRL = 0x10
def main (default_directory='.'):
PCB_VER_MASK = 0x000F
CARRIER_TYPE_MASK = 0xFFFF0000
# Constants declaration
EXPECTED_BITSTREAM_TYPE = 0x1
STATUS_FMC_PRES = (1<<0)
STATUS_P2L_PLL_LCK = (1<<1)
STATUS_SYS_PLL_LCK = (1<<2)
STATUS_DDR3_CAL_DONE = (1<<3)
CTRL_LED_GREEN = (1<<0)
CTRL_LED_RED = (1<<1)
CTRL_DAC_CLR_N = (1<<2)
start_test_time = time.time()
print "================================================================================"
print "Test01 start\n"
FAMILY_CODE = 0x28
# SPEC object declaration
print "Loading hardware access library and opening device.\n"
spec = rr.Gennum()
def main (default_directory='.'):
# Carrier object declaration (SPEC board specific part)
try:
carrier = CFmcAdc100mSpec(spec, EXPECTED_BITSTREAM_TYPE)
except FmcAdc100mSpecOperationError as e:
raise PtsCritical("Carrier init failed, test stopped: %s" % e)
"""
path_fpga_loader = '../../../gnurabbit/user/fpga_loader';
path_firmware = '../firmwares/spec_fmcadc100m14b4cha.bin';
# Mezzanine object declaration (FmcAdc100m14b4cha board specific part)
try:
fmc = CFmcAdc100m(spec)
except FmcAdc100mOperationError as e:
raise PtsCritical("Mezzanine init failed, test stopped: %s" % e)
firmware_loader = os.path.join(default_directory, path_fpga_loader)
bitstream = os.path.join(default_directory, path_firmware)
print firmware_loader + ' ' + bitstream
os.system( firmware_loader + ' ' + bitstream )
time.sleep(2);
"""
# Objects declaration
spec = rr.Gennum() # bind to the SPEC board
carrier_csr = csr.CCSR(spec, CARRIER_CSR)
fmc = fmc_adc.CFmcAdc100Ms(spec)
# Read unique ID and print to log
unique_id = fmc.get_unique_id()
......
......@@ -137,7 +137,7 @@ def main (default_directory='.'):
#---------------------------------------------------------------------------
print('Set positive offset: %.4X' % OFFSET_POS)
for i in range(1, NB_CHANNELS+1):
fmc.dc_offset_calibr(i, OFFSET_POS)
fmc.set_dc_offset(i, OFFSET_POS)
time.sleep(DAC_SET_SLEEP)
# Read channels
......@@ -172,7 +172,7 @@ def main (default_directory='.'):
#---------------------------------------------------------------------------
print('Set negative offset: %.4X' % OFFSET_NEG)
for i in range(1, NB_CHANNELS+1):
fmc.dc_offset_calibr(i, OFFSET_NEG)
fmc.set_dc_offset(i, OFFSET_NEG)
time.sleep(DAC_SET_SLEEP)
# Read channels
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment