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