Commit a6719521 authored by Matthieu Cattin's avatar Matthieu Cattin

fmc_adc_svec: Add svec access class + registers descriptions

parent e35306e8
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2013
# 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 time
import random
import math
# Import specific modules
from csr import *
from onewire import *
from gn4124 import *
from ds18b20 import *
# Import register maps
from svec_carrier_csr import *
from svec_irq_controller_regs import *
# Global constants
LED_COLOR = {"OFF":0x0, "GREEN":0x1, "RED":0x2, "ORANGE":0x3}
# Class to access fmcadc100m14b4cha SVEC specific Wishbone cores
class FmcAdc100mSvecOperationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return ("FmcAdc100mSvec: %s" %(self.msg))
class CFmcAdc100mSvec:
# Wishbone core base addresses
I2C_ADDR = 0x1000
ONEWIRE_ADDR = 0x1100
CSR_ADDR = 0x1200
IRQ_CONTROLLER_ADDR = 0x1300
# Onewire core port
DS18B20_PORT = 0
# IRQ controller
IRQ_SRC_DMA_END = 0x1
IRQ_SRC_DMA_ERR = 0x2
IRQ_SRC_ACQ_TRG = 0x4
IRQ_SRC_ACQ_END = 0x8
#======================================================================
# Class initialisation
def __init__(self, bus, bs_type):
self.bus = bus
# Objects declaration
self.i2c = COpenCoresI2C(self.bus, self.I2C_ADDR, 249)
self.onewire = COpenCoresOneWire(self.bus, self.ONEWIRE_ADDR, 624, 124)
self.ds18b20 = CDS18B20(self.onewire, self.DS18B20_PORT)
self.csr = CCSR(self.bus, self.CSR_ADDR, CARRIER_CSR)
self.irq_controller = CCSR(self.bus, self.IRQ_CONTROLLER_ADDR, IRQ_CONTROLLER_REGS)
# Check if bitstream is properly loaded by reading a register
ct = self.get_carrier_type()
if(ct == 0xFFFFFFFF):
raise FmcAdc100mSvecOperationError("Bitstream not properly loaded.")
# TODO
# Check if the expected bitstream loaded
#bs = self.get_bitstream_type()
#if(bs != bs_type):
# raise FmcAdc100mSvecOperationError("Wrong bitsream. Excpect:0x%08X, Read:0x%08X" % (bs_type, bs))
# Ckeck if a mezzanine is present
if(not self.get_fmc_presence()):
raise FmcAdc100mSvecOperationError("Mezzanine not present or PRSNT_M2C_L line faulty.")
#======================================================================
# Control and status registers (CSR)
# Print carrier CSR register map
def print_csr(self):
self.csr.print_reg_map()
# Get carrier type
def get_carrier_type(self):
try:
return self.csr.get_field('CARRIER', 'TYPE')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get PCB revision
def get_pcb_rev(self):
try:
return self.csr.get_field('CARRIER', 'PCB_REV')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get status register value
def get_status(self):
try:
return self.csr.get_reg('STAT')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get control register value
def get_control(self):
try:
return self.csr.get_reg('CTRL')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get FMC presence state
# 1 = mezzanine present, 0 = no nezzanine
def get_fmc_presence(self, slot):
try:
if slot == 0:
fmc = 'FMC0_PRES'
else if slot == 1:
fmc = 'FMC1_PRES'
else:
raise FmcAdc100mSvecOperationError("Slot number out of range [0:1]")
return not self.csr.get_field('STAT', fmc)
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get system clock PLL lock state
def get_sys_pll_lock(self):
try:
return self.csr.get_field('STAT', 'SYS_PLL_LCK')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get DDR3 controller calibration done state
def get_ddr0_cal_done(self, ddr):
try:
if ddr == 0:
val = 'DDR0_CAL_DONE'
else if ddr == 1:
val = 'DDR1_CAL_DONE'
else:
raise FmcAdc100mSvecOperationError("DDR number out of range [0:1]")
return self.csr.get_field('STAT', val)
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Set front panel LEDs
def set_led(self, led, color):
try:
val = self.csr.get_field('CTRL', 'LED')
val &= ~(0x3 << 2*(led-1))
val |= (0x3 & LED_COLOR[color]) << 2*(led-1)
return self.csr.set_field('CTRL', 'LED', val)
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
#======================================================================
# Onewire thermometer and unique ID
# print SVEC unique ID
def print_unique_id(self):
try:
print('SVEC unique ID: %.12X') % self.ds18b20.read_serial_number()
except DS18B20OperationError as e:
raise FmcAdc100mSvecOperationError(e)
# print SVEC temperature
def print_temp(self):
try:
serial_number = self.ds18b20.read_serial_number()
print("SVEC temperature: %3.3f°C") % self.ds18b20.read_temp(serial_number)
except DS18B20OperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Returns SVEC unique ID
def get_unique_id(self):
try:
return self.ds18b20.read_serial_number()
except DS18B20OperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Returns SVEC temperature
def get_temp(self):
try:
serial_number = self.ds18b20.read_serial_number()
return self.ds18b20.read_temp(serial_number)
except DS18B20OperationError as e:
raise FmcAdc100mSvecOperationError(e)
#======================================================================
# Interrupt controller core
# Print IRQ controller register map
def print_irq_controller_regs(self):
self.irq_controller.print_reg_map()
# Set IRQ enable mask
def set_irq_en_mask(self, mask):
try:
self.irq_controller.set_reg('EN_MASK', mask)
return self.irq_controller.get_reg('EN_MASK')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Get IRQ enable mask
def get_irq_en_mask(self):
try:
return self.irq_controller.get_reg('EN_MASK')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Returns multiple IRQ status
def get_irq_mult(self):
try:
return self.irq_controller.get_reg('MULTI_IRQ')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Clears multiple IRQ status
def clear_irq_mult(self, irq):
try:
self.irq_controller.set_reg('MULTI_IRQ', irq)
return self.irq_controller.get_reg('MULTI_IRQ')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Returns IRQ source
def get_irq_source(self):
try:
return self.irq_controller.get_reg('SRC')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Clears IRQ source
def clear_irq_source(self, irq):
try:
self.irq_controller.set_reg('SRC', irq)
return self.irq_controller.get_reg('SRC')
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Set acquisition end interrupt mask
def set_irq_acq_end_mask(self, slot, value):
try:
if slot == 0:
fmc = 'FMC0_ACQ_END'
else if slot == 1:
fmc = 'FMC1_ACQ_END'
else:
raise FmcAdc100mSvecOperationError("Slot number out of range [0:1]")
return self.irq_controller.set_field('EN_MASK', fmc, value)
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
# Set trigger interrupt mask
def set_irq_trig_mask(self, slot, value):
try:
if slot == 0:
fmc = 'FMC0_ACQ_TRG'
else if slot == 1:
fmc = 'FMC1_ACQ_TRG'
else:
raise FmcAdc100mSvecOperationError("Slot number out of range [0:1]")
return self.irq_controller.set_field('EN_MASK', fmc, value)
except CSRDeviceOperationError as e:
raise FmcAdc100mSvecOperationError(e)
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2013
# Author: Matthieu Cattin (CERN)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 8/5/2012
# Control and status registers of the SVEC board
CARRIER_CSR=['Carrier control and status registers',{
'CARRIER':[0x00, 'Carrier', {
'PCB_REV':[0, 'PCB revision', 0x1F],
'RESERVED':[5, 'Reserved', 0x7FF],
'TYPE':[16, 'Carrier type', 0xFFFF]}],
'STAT':[0x04, 'Status', {
'FMC0_PRES':[0, 'FMC 1 presence (active low)', 0x1],
'FMC1_PRES':[1, 'FMC 2 presence (active low)', 0x1],
'SYS_PLL_LCK':[2, 'System PLL locked', 0x1],
'DDR0_CAL_DONE':[3, 'DDR3 bank 4 calibration done', 0x1],
'DDR1_CAL_DONE':[4, 'DDR3 bank 5 calibration done', 0x1],
'RESERVED':[5, 'Reserved', 0xFFFFFFF]}],
'CTRL':[0x08, 'Control', {
'LED':[0, 'Front panel LEDs', 0xFFFF],
'RESERVED':[16, 'Reserved', 0xFFFF]}]
}]
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2013
# Author: Matthieu Cattin (CERN)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 8/5/2012
# IRQ controller core registers
IRQ_CONTROLLER_REGS=['IRQ controller registers', {
'MULTI_IRQ':[0x00, 'Multiple interrupt', {
'FMC0_ACQ_TRG':[0, 'FMC 1 acquisition triggered', 0x1],
'FMC0_ACQ_END':[1, 'FMC 1 acquisition finished', 0x1],
'FMC1_ACQ_TRG':[2, 'FMC 2 acquisition triggered', 0x1],
'FMC1_ACQ_END':[3, 'FMC 2 acquisition finished', 0x1],
'RESERVED':[4, 'Reserved', 0xFFFFFFF]}],
'SRC':[0x04, 'Interrupt sources', {
'FMC0_ACQ_TRG':[0, 'FMC 1 acquisition triggered', 0x1],
'FMC0_ACQ_END':[1, 'FMC 1 acquisition finished', 0x1],
'FMC1_ACQ_TRG':[2, 'FMC 2 acquisition triggered', 0x1],
'FMC1_ACQ_END':[3, 'FMC 2 acquisition finished', 0x1],
'RESERVED':[4, 'Reserved', 0xFFFFFFF]}],
'EN_MASK':[0x08, 'Interrupt enable mask', {
'FMC0_ACQ_TRG':[0, 'FMC 1 acquisition triggered', 0x1],
'FMC0_ACQ_END':[1, 'FMC 1 acquisition finished', 0x1],
'FMC1_ACQ_TRG':[2, 'FMC 2 acquisition triggered', 0x1],
'FMC1_ACQ_END':[3, 'FMC 2 acquisition finished', 0x1],
'RESERVED':[4, 'Reserved', 0xFFFFFFF]}]
}]
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