Commit ce1dbfb5 authored by Matthieu Cattin's avatar Matthieu Cattin

Add new common/ directory to store common modules.

Add a first set of common modules from fmcadc100m14b4cha.
parent 26214ae5
#!/usr/bin/python
import sys
import rr
import time
class CCSR:
def __init__(self, bus, base_addr):
self.base_addr = base_addr;
self.bus = bus;
def wr_reg(self, addr, val):
#print(" wr:%.8X reg:%.8X")%(val,(self.base_addr+addr))
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
reg = self.bus.iread(0, self.base_addr + addr, 4)
#print(" reg:%.8X value:%.8X")%((self.base_addr+addr), reg)
return reg
def wr_bit(self, addr, bit, value):
reg = self.rd_reg(addr)
if(0==value):
reg &= ~(1<<bit)
else:
reg |= (1<<bit)
self.wr_reg(addr, reg)
def rd_bit(self, addr, bit):
if(self.rd_reg(addr) & (1<<bit)):
return 1
else:
return 0
#!/usr/bin/python
import sys
import rr
import time
import onewire
class CDS18B20:
# ROM commands
ROM_SEARCH = 0xF0
ROM_READ = 0x33
ROM_MATCH = 0x55
ROM_SKIP = 0xCC
ROM_ALARM_SEARCH = 0xEC
# DS18B20 fonctions commands
CONVERT_TEMP = 0x44
WRITE_SCRATCHPAD = 0x4E
READ_SCRATCHPAD = 0xBE
COPY_SCRATCHPAD = 0x48
RECALL_EEPROM = 0xB8
READ_POWER_SUPPLY = 0xB4
# Thermometer resolution configuration
RES = {'9-bit':0x0, '10-bit':0x1, '11-bit':0x2, '12-bit':0x3}
def __init__(self, onewire, port):
self.onewire = onewire
self.port = port
def read_serial_number(self):
#print('[DS18B20] Reading serial number')
if(1 != self.onewire.reset(self.port)):
print('[DS18B20] No presence pulse detected')
return -1
else:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_READ
err = self.onewire.write_byte(self.port, self.ROM_READ)
if(err != 0):
print('[DS18B20] Write error')
return -1
family_code = self.onewire.read_byte(self.port)
serial_number = 0
for i in range(6):
serial_number |= self.onewire.read_byte(self.port) << (i*8)
crc = self.onewire.read_byte(self.port)
#print('[DS18B20] Family code : %.2X') % family_code
#print('[DS18B20] Serial number: %.12X') % serial_number
#print('[DS18B20] CRC : %.2X') % crc
return ((crc<<56) | (serial_number<<8) | family_code)
def access(self, serial_number):
#print('[DS18B20] Accessing device')
if(1 != self.onewire.reset(self.port)):
print('[DS18B20] No presence pulse detected')
return -1
else:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_MATCH
err = self.onewire.write_byte(self.port, self.ROM_MATCH)
#print serial_number
block = []
for i in range(8):
block.append(serial_number & 0xFF)
serial_number >>= 8
#print block
self.onewire.write_block(self.port, block)
return 0
def read_temp(self, serial_number):
#print('[DS18B20] Reading temperature')
err = self.access(serial_number)
#print('[DS18B20] Write function command %.2X') % self.CONVERT_TEMP
err = self.onewire.write_byte(self.port, self.CONVERT_TEMP)
time.sleep(0.8)
err = self.access(serial_number)
#print('[DS18B20] Write function command %.2X') % self.READ_SCRATCHPAD
err = self.onewire.write_byte(self.port, self.READ_SCRATCHPAD)
data = self.onewire.read_block(self.port, 9)
#for i in range(9):
# print('Scratchpad data[%1d]: %.2X') % (i, data[i])
temp = (data[1] << 8) | (data[0])
if(temp & 0x1000):
temp = -0x10000 + temp
temp = temp/16.0
return temp
# Set temperature thresholds
# Configure thermometer resolution
#!/usr/bin/python
import sys
import rr
import time
import i2c
class C24AA64:
def __init__(self, i2c, i2c_addr):
self.i2c = i2c
self.i2c_addr = i2c_addr
def wr_data(self, mem_addr, data):
if len(data) > 32:
print "Maximum sequence write size is 32 byte!"
return -1;
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
#print('24AA64:write: data lenght=%d')%(len(data))
for i in range(len(data)-1):
#print('24AA64:write: i=%d')%(i)
self.i2c.write(data[i],False)
if len(data) > 1:
i += 1
else:
i = 0
#print('24AA64:write:last i=%d')%(i)
self.i2c.write(data[i],True)
return 0;
def rd_data(self, mem_addr, size):
self.i2c.start(self.i2c_addr, True)
self.i2c.write((mem_addr >> 8), False)
self.i2c.write((mem_addr & 0xFF), False)
self.i2c.start(self.i2c_addr, False)
data = []
#print('24AA64:read: data lenght=%d')%(size)
for i in range(size-1):
data.append(self.i2c.read(False))
#print('24AA64:read: i=%d')%(i)
#print('24AA64:read:last i=%d')%(i)
data.append(self.i2c.read(True))
return data;
#!/usr/bin/python
import sys
import rr
import time
import csr
class CGN4124:
# Host registers (BAR12), for DMA items storage
HOST_BAR = 0xC
HOST_DMA_CARRIER_START_ADDR = 0x00
HOST_DMA_HOST_START_ADDR_L = 0x04
HOST_DMA_HOST_START_ADDR_H = 0x08
HOST_DMA_LENGTH = 0x0C
HOST_DMA_NEXT_ITEM_ADDR_L = 0x10
HOST_DMA_NEXT_ITEM_ADDR_H = 0x14
HOST_DMA_ATTRIB = 0x18
# GN4124 chip registers (BAR4)
GN4124_BAR = 0x4
R_PCI_SYS_CFG = 0x800
R_CLK_CSR = 0x808
R_INT_CFG0 = 0x820
R_GPIO_DIR_MODE = 0xA04
R_GPIO_INT_MASK_CLR = 0xA18
R_GPIO_INT_MASK_SET = 0xA1C
R_GPIO_INT_STATUS = 0xA20
R_GPIO_INT_VALUE = 0xA28
CLK_CSR_DIVOT_MASK = 0x3F0
INT_CFG0_GPIO = 15
GPIO_INT_SRC = 8
# GN4124 core registers (BAR0)
R_DMA_CTL = 0x00
R_DMA_STA = 0x04
R_DMA_CARRIER_START_ADDR = 0x08
R_DMA_HOST_START_ADDR_L = 0x0C
R_DMA_HOST_START_ADDR_H = 0x10
R_DMA_LENGTH = 0x14
R_DMA_NEXT_ITEM_ADDR_L = 0x18
R_DMA_NEXT_ITEM_ADDR_H = 0x1C
R_DMA_ATTRIB = 0x20
DMA_CTL_START = 0
DMA_CTL_ABORT = 1
DMA_CTL_SWAP = 2
DMA_STA = ['Idle','Done','Busy','Error','Aborted']
DMA_ATTRIB_LAST = 0
DMA_ATTRIB_DIR = 1
def rd_reg(self, bar, addr):
return self.bus.iread(bar, addr, 4)
def wr_reg(self, bar, addr, value):
self.bus.iwrite(bar, addr, 4, value)
def __init__(self, bus, csr_addr):
self.bus = bus
self.dma_csr = csr.CCSR(bus, csr_addr)
self.dma_item_cnt = 0
# Get page list
self.pages = self.bus.getplist()
# Shift by 12 to get the 32-bit physical addresses
self.pages = [addr << 12 for addr in self.pages]
self.set_interrupt_config()
# Enable interrupt from gn4124
self.bus.irqena()
# Set local bus frequency
def set_local_bus_freq(self, freq):
# freq in MHz
# LCLK = (25MHz*(DIVFB+1))/(DIVOT+1)
# DIVFB = 31
# DIVOT = (800/LCLK)-1
divot = int(round((800/freq)-1,0))
#print '%d' % divot
data = 0xe001f00c + (divot << 4)
#print '%.8X' % data
#print 'Set local bus freq to %dMHz' % int(round(800/(divot+1),0))
self.wr_reg(self.GN4124_BAR, self.R_CLK_CSR, data)
# Get local bus frequency
# return: frequency in MHz
def get_local_bus_freq(self):
reg = self.rd_reg(self.GN4124_BAR, self.R_CLK_CSR)
divot = ((reg & self.CLK_CSR_DIVOT_MASK)>>4)
return (800/(divot + 1))
# Get physical addresses of the pages allocated to GN4124
def get_physical_addr(self):
return self.pages
# Wait for interrupt
def wait_irq(self):
# Add here reading of the interrupt source (once the irq core will be present)
return self.bus.irqwait()
# GN4124 RSTOUT33 assert/de-assert cycle
def rstout33_cycle(self):
# assert RSTOUT33 pin
self.wr_reg(self.GN4124_BAR, self.R_PCI_SYS_CFG, 0x00021040)
# de-assert RSTOUT33 pin
self.wr_reg(self.GN4124_BAR, self.R_PCI_SYS_CFG, 0x00025000)
# GN4124 interrupt configuration
def set_interrupt_config(self):
# Set interrupt line from FPGA (GPIO8) as input
self.wr_reg(self.GN4124_BAR, self.R_GPIO_DIR_MODE, (1<<self.GPIO_INT_SRC))
# Set interrupt mask for all GPIO except for GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_MASK_SET, ~(1<<self.GPIO_INT_SRC))
# Make sure the interrupt mask is cleared for GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_MASK_CLR, (1<<self.GPIO_INT_SRC))
# Interrupt on rising edge of GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_VALUE, (1<<self.GPIO_INT_SRC))
# GPIO as interrupt 0 source
self.wr_reg(self.GN4124_BAR, self.R_INT_CFG0, (1<<self.INT_CFG0_GPIO))
# Get DMA controller status
def get_dma_status(self):
reg = self.dma_csr.rd_reg(self.R_DMA_STA)
if(reg > len(self.DMA_STA)):
print("DMA status register : %.8X") % reg
raise Exception('Invalid DMA status')
else:
return self.DMA_STA[reg]
# Configure DMA byte swapping
# 0 = A1 B2 C3 D4 (straight)
# 1 = B2 A1 D4 C3 (swap bytes in words)
# 2 = C3 D4 A1 B2 (swap words)
# 3 = D4 C3 B2 A1 (invert bytes)
def set_dma_swap(self, swap):
if(swap > 3):
raise Exception('Invalid swapping configuration : %d') % swap
else:
self.dma_csr.wr_reg(self.R_CTL, (swap << self.DMA_CTL_SWAP))
# Add DMA item (first item is on the board, the following in the host memory)
# carrier_addr, host_addr, length and next_item_addr are in bytes
# dma_dir = 1 -> PCIe to carrier
# dma_dir = 0 -> carrier to PCIe
# dma_last = 0 -> last item in the transfer
# dma_last = 1 -> more item in the transfer
# Only supports 32-bit host address
def add_dma_item(self, carrier_addr, host_addr, length, dma_dir, last_item):
if(0 == self.dma_item_cnt):
# write the first DMA item in the carrier
self.dma_csr.wr_reg(self.R_DMA_CARRIER_START_ADDR, carrier_addr)
self.dma_csr.wr_reg(self.R_DMA_HOST_START_ADDR_L, (host_addr & 0xFFFFFFFF))
self.dma_csr.wr_reg(self.R_DMA_HOST_START_ADDR_H, (host_addr >> 32))
self.dma_csr.wr_reg(self.R_DMA_LENGTH, length)
self.dma_csr.wr_reg(self.R_DMA_NEXT_ITEM_ADDR_L, (self.pages[0] & 0xFFFFFFFF))
self.dma_csr.wr_reg(self.R_DMA_NEXT_ITEM_ADDR_H, 0x0)
attrib = (dma_dir << self.DMA_ATTRIB_DIR) + (last_item << self.DMA_ATTRIB_LAST)
self.dma_csr.wr_reg(self.R_DMA_ATTRIB, attrib)
else:
# write nexy DMA item(s) in host memory
# uses page 0 to store DMA items
# current and next item addresses are automatically set
current_item_addr = (self.dma_item_cnt-1)*0x20
next_item_addr = (self.dma_item_cnt)*0x20
self.wr_reg(self.HOST_BAR, self.HOST_DMA_CARRIER_START_ADDR + current_item_addr, carrier_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_HOST_START_ADDR_L + current_item_addr, host_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_HOST_START_ADDR_H + current_item_addr, 0x0)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_LENGTH + current_item_addr, length)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_NEXT_ITEM_ADDR_L + current_item_addr,
self.pages[0] + next_item_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_NEXT_ITEM_ADDR_H + current_item_addr, 0x0)
attrib = (dma_dir << self.DMA_ATTRIB_DIR) + (last_item << self.DMA_ATTRIB_LAST)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_ATTRIB + current_item_addr, attrib)
self.dma_item_cnt += 1
# Start DMA transfer
def start_dma(self):
self.dma_item_cnt = 0
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_START, 1)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
#while(('Idle' == self.get_dma_status()) or
# ('Busy' == self.get_dma_status())):
# pass
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_START, 0)
# Abort DMA transfer
def abort_dma(self):
self.dma_item_cnt = 0
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_ABORT, 1)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
while('Aborted' != self.get_dma_status()):
pass
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_ABORT, 0)
# Get memory page
def get_memory_page(self, page_nb):
data = []
for i in range(2**10):
data.append(self.rd_reg(self.HOST_BAR, (page_nb<<12)+(i<<2)))
return data
# Set memory page
def set_memory_page(self, page_nb, pattern):
for i in range(2**10):
self.wr_reg(self.HOST_BAR, (page_nb<<12)+(i<<2), pattern)
#!/usr/bin/python
import sys
import rr
import time
class COpenCoresI2C:
# OpenCores I2C registers description
R_PREL = 0x0
R_PREH = 0x4
R_CTR = 0x8
R_TXR = 0xC
R_RXR = 0xC
R_CR = 0x10
R_SR = 0x10
CTR_EN = (1<<7)
CR_STA = (1<<7)
CR_STO = (1<<6)
CR_RD = (1<<5)
CR_WR = (1<<4)
CR_ACK = (1<<3)
SR_RXACK = (1<<7)
SR_TIP = (1<<1)
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self,addr):
return self.bus.iread(0, self.base_addr + addr, 4)
# Function called during object creation
# bus = host bus (PCIe, VME, etc...)
# base_addr = I2C core base address
# prescaler = SCK prescaler, prescaler = (Fsys/(5*Fsck))-1
def __init__(self, bus, base_addr, prescaler):
self.bus = bus
self.base_addr = base_addr
self.wr_reg(self.R_CTR, 0)
#print("prescaler: %.4X") % prescaler
self.wr_reg(self.R_PREL, (prescaler & 0xff))
#print("PREL: %.2X") % self.rd_reg(self.R_PREL)
self.wr_reg(self.R_PREH, (prescaler >> 8))
#print("PREH: %.2X") % self.rd_reg(self.R_PREH)
self.wr_reg(self.R_CTR, self.CTR_EN)
#print("CTR: %.2X") % self.rd_reg(self.R_CTR)
if(not(self.rd_reg(self.R_CTR) & self.CTR_EN)):
print "Warning! I2C core is not enabled!"
def wait_busy(self):
while(self.rd_reg(self.R_SR) & self.SR_TIP):
pass
def start(self, addr, write_mode):
#print('i2c:start: addr=%.2X')%addr
addr = addr << 1
#print('i2c:start: addr=%.2X')%addr
if(write_mode == False):
addr = addr | 1
#print('i2c:start: addr=%.2X')%addr
self.wr_reg(self.R_TXR, addr)
#print("R_TXR: %.2X") % self.rd_reg(self.R_TXR)
self.wr_reg(self.R_CR, self.CR_STA | self.CR_WR)
self.wait_busy()
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon address (device 0x%x not connected?)' % addr)
return "nack"
else:
return "ack"
def write(self, data, last):
self.wr_reg(self.R_TXR, data)
cmd = self.CR_WR
if(last):
cmd = cmd | self.CR_STO
self.wr_reg(self.R_CR, cmd)
self.wait_busy()
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon write')
def read(self, last):
cmd = self.CR_RD
if(last):
cmd = cmd | self.CR_STO | self.CR_ACK
self.wr_reg(self.R_CR, cmd)
self.wait_busy()
return self.rd_reg(self.R_RXR)
def scan(self):
periph_addr = []
for i in range(0,128):
addr = i << 1
addr |= 1
self.wr_reg(self.R_TXR, addr)
self.wr_reg(self.R_CR, self.CR_STA | self.CR_WR)
self.wait_busy()
if(not(self.rd_reg(self.R_SR) & self.SR_RXACK)):
periph_addr.append(i)
print("Device found at address: 0x%.2X") % i
self.wr_reg(self.R_TXR, 0)
self.wr_reg(self.R_CR, self.CR_STO | self.CR_WR)
self.wait_busy()
return periph_addr
##########################################
# Usage example
#gennum = rr.Gennum();
#i2c = COpenCoresI2C(gennum, 0x80000, 500);
#!/usr/bin/python
import sys
import rr
import time
import spi
class CLTC217x:
R_RST = 0x00
R_FMT = 0x01
R_OUTMODE = 0x02
R_TESTPAT_MSB = 0x03
R_TESTPAT_LSB = 0x04
RST = (1<<7)
FMT_DCSOFF = (1<<7)
FMT_RAND = (1<<6)
FMT_TWOSCOMP = (1<<5)
FMT_SLEEP = (1<<4)
FMT_CH4_NAP = (1<<3)
FMT_CH3_NAP = (1<<2)
FMT_CH2_NAP = (1<<1)
FMT_CH1_NAP = (1<<0)
OUTMODE_ILVDS_3M5 = (0<<5)
OUTMODE_ILVDS_4M0 = (1<<5)
OUTMODE_ILVDS_4M5 = (2<<5)
OUTMODE_ILVDS_3M0 = (4<<5)
OUTMODE_ILVDS_2M5 = (5<<5)
OUTMODE_ILVDS_2M1 = (6<<5)
OUTMODE_ILVDS_1M75 = (7<<5)
OUTMODE_TERMON = (1<<4)
OUTMODE_OUTOFF = (1<<3)
OUTMODE_2L_16B = (0<<0)
OUTMODE_2L_14B = (1<<0)
OUTMODE_2L_12B = (2<<0)
OUTMODE_1L_14B = (5<<0)
OUTMODE_1L_12B = (6<<0)
OUTMODE_1L_16B = (7<<0)
TESTPAT_MSB_OUTTEST = (1<<7)
TESTPAT_MSB_MASK = 0x3F
TESTPAT_LSB_MASK = 0xFF
# addr = ltc217x register address (1 byte)
# value = value to write to the register (1 byte)
def wr_reg(self, addr, value):
tx = [value, addr]
self.spi.transaction(self.slave, tx)
def rd_reg(self, addr):
tx = [0xFF, (addr | 0x80)]
rx = self.spi.transaction(self.slave, tx)
return (rx[0] & 0xFF)
def __init__(self, spi, slave):
self.spi = spi
self.slave = slave
self.wr_reg(self.R_RST, self.RST)
#self.wr_reg(self.R_FMT, 0)
self.wr_reg(self.R_FMT, self.FMT_TWOSCOMP)
#self.wr_reg(self.R_OUTMODE, (self.OUTMODE_ILVDS_4M5 | self.OUTMODE_2L_16B | self.OUTMODE_TERMON))
#self.wr_reg(self.R_OUTMODE, (self.OUTMODE_ILVDS_2M5 | self.OUTMODE_2L_16B | self.OUTMODE_TERMON))
self.wr_reg(self.R_OUTMODE, (self.OUTMODE_ILVDS_4M5 | self.OUTMODE_2L_16B))
def get_fmt(self):
return self.rd_reg(self.R_FMT)
def get_outmode(self):
return self.rd_reg(self.R_OUTMODE)
def get_testpat(self):
return (((self.rd_reg(self.R_TESTPAT_MSB) & self.TESTPAT_MSB_MASK)<<8)
+ (self.rd_reg(self.R_TESTPAT_LSB) & self.TESTPAT_LSB_MASK))
def get_testpat_stat(self):
return ((self.rd_reg(self.R_TESTPAT_MSB))>>7)
def set_testpat(self, pattern):
self.wr_reg(self.R_TESTPAT_MSB, ((pattern>>8) & self.TESTPAT_MSB_MASK))
self.wr_reg(self.R_TESTPAT_LSB, (pattern & self.TESTPAT_LSB_MASK))
def en_testpat(self):
reg = self.rd_reg(self.R_TESTPAT_MSB)
reg |= self.TESTPAT_MSB_OUTTEST
self.wr_reg(self.R_TESTPAT_MSB, reg)
def dis_testpat(self):
reg = self.rd_reg(self.R_TESTPAT_MSB)
reg &= ~self.TESTPAT_MSB_OUTTEST
self.wr_reg(self.R_TESTPAT_MSB, reg)
def print_regs(self):
print '\nLTC217x registers:'
for i in range(0,5):
print("reg %d: %.2X") % (i, self.rd_reg(i))
#!/usr/bin/python
import sys
import rr
import time
import spi
import csr
class CMAX5442:
def __init__(self, spi, slave):
self.spi = spi
self.slave = slave
# offset = value to write to the DAC (2 bytes)
def set_offset(self, offset):
tx = [(offset & 0xFF), ((offset & 0xFF00)>>8)]
#print('[max5442] Set offset: %.4X') % offset
#for i in range(len(tx)):
# print('[max5442] tx[%d]: %.2X') %(i, tx[i])
self.spi.transaction(self.slave, tx)
#!/usr/bin/python
import sys
import rr
import time
class COpenCoresOneWire:
# OpenCores 1-wire registers description
R_CSR = 0x0
R_CDR = 0x4
CSR_DAT_MSK = (1<<0)
CSR_RST_MSK = (1<<1)
CSR_OVD_MSK = (1<<2)
CSR_CYC_MSK = (1<<3)
CSR_PWR_MSK = (1<<4)
CSR_IRQ_MSK = (1<<6)
CSR_IEN_MSK = (1<<7)
CSR_SEL_OFS = 8
CSR_SEL_MSK = (0xF<<8)
CSR_POWER_OFS = 16
CSR_POWER_MSK = (0xFFFF<<16)
CDR_NOR_MSK = (0xFFFF<<0)
CDR_OVD_OFS = 16
CDR_OVD_MSK = (0XFFFF<<16)
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self,addr):
return self.bus.iread(0, self.base_addr + addr, 4)
# Function called during object creation
# bus = host bus (PCIe, VME, etc...)
# base_addr = 1-wire core base address
# clk_div_nor = clock divider normal operation, clk_div_nor = Fclk * 5E-6 - 1
# clk_div_ovd = clock divider overdrive operation, clk_div_ovd = Fclk * 1E-6 - 1
def __init__(self, bus, base_addr, clk_div_nor, clk_div_ovd):
self.bus = bus
self.base_addr = base_addr
#print('\n### Onewire class init ###')
#print("Clock divider (normal operation): %.4X") % clk_div_nor
#print("Clock divider (overdrive operation): %.4X") % clk_div_ovd
data = ((clk_div_nor & self.CDR_NOR_MSK) | ((clk_div_ovd<<self.CDR_OVD_OFS) & self.CDR_OVD_MSK))
#print('CRD register wr: %.8X') % data
self.wr_reg(self.R_CDR, data)
#print('CRD register rd: %.8X') % self.rd_reg(self.R_CDR)
# return: 1 -> presence pulse detected
# 0 -> no presence pulse detected
def reset(self, port):
data = ((port<<self.CSR_SEL_OFS) & self.CSR_SEL_MSK) | self.CSR_CYC_MSK | self.CSR_RST_MSK
#print('[onewire] Sending reset command, CSR: %.8X') % data
self.wr_reg(self.R_CSR, data)
while(self.rd_reg(self.R_CSR) & self.CSR_CYC_MSK):
pass
reg = self.rd_reg(self.R_CSR)
#print('[onewire] Reading CSR: %.8X') % reg
return ~reg & self.CSR_DAT_MSK
def slot(self, port, bit):
data = ((port<<self.CSR_SEL_OFS) & self.CSR_SEL_MSK) | self.CSR_CYC_MSK | (bit & self.CSR_DAT_MSK)
self.wr_reg(self.R_CSR, data)
while(self.rd_reg(self.R_CSR) & self.CSR_CYC_MSK):
pass
reg = self.rd_reg(self.R_CSR)
return reg & self.CSR_DAT_MSK
def read_bit(self, port):
return self.slot(port, 0x1)
def write_bit(self, port, bit):
return self.slot(port, bit)
def read_byte(self, port):
data = 0
for i in range(8):
data |= self.read_bit(port) << i
return data
def write_byte(self, port, byte):
data = 0
byte_old = byte
for i in range(8):
data |= self.write_bit(port, (byte & 0x1)) << i
byte >>= 1
if(byte_old == data):
return 0
else:
return -1
def write_block(self, port, block):
if(160 < len(block)):
return -1
data = []
for i in range(len(block)):
data.append(self.write_byte(port, block[i]))
return data
def read_block(self, port, length):
if(160 < length):
return -1
data = []
for i in range(length):
data.append(self.read_byte(port))
return data
#!/usr/bin/python
import sys
import rr
import time
import i2c
class CSi57x:
R_HS = 0x07
R_RFREQ4 = 0x08
R_RFREQ3 = 0x09
R_RFREQ2 = 0x0A
R_RFREQ1 = 0x0B
R_RFREQ0 = 0x0C
R_RFMC = 0x87
R_FDCO = 0x89
HS_DIV_MASK = 0xE0
N1_H_MASK = 0x1F
N1_L_MASK = 0xC0
RFREQ4_MASK = 0x3F
RFMC_RST = (1<<7)
RFMC_NEW_FREQ = (1<<6)
RFMC_FREEZE_M = (1<<5)
RFMC_FREEZE_VCADC = (1<<4)
RFMC_RECALL = (1<<0)
FDCO_FREEZE_DCO = (1<<4)
HS_DIV = [4, 5, 6, 7, 0, 9, 0, 11]
def __init__(self, i2c, addr):
self.i2c = i2c
self.addr = addr
def rd_reg(self, addr):
self.i2c.start(self.addr, True)
self.i2c.write(addr, False)
self.i2c.start(self.addr, False)
reg = self.i2c.read(True)
#print("raw data from Si570: %.2X")%reg
return reg
def wr_reg(self, addr, data):
self.i2c.start(self.addr, True)
self.i2c.write(addr, False)
self.i2c.write(data, True)
def get_rfreq(self):
rfreq = self.rd_reg(self.R_RFREQ0)
rfreq += (self.rd_reg(self.R_RFREQ1)<<8)
rfreq += (self.rd_reg(self.R_RFREQ2)<<16)
rfreq += (self.rd_reg(self.R_RFREQ3)<<24)
rfreq += ((self.rd_reg(self.R_RFREQ4) & self.RFREQ4_MASK)<<32)
return (rfreq>>28)+((rfreq & 0x0FFFFFFF)/2.0**28)
def get_n1_div(self):
n1 = ((self.rd_reg(self.R_RFREQ4) & self.N1_L_MASK)>>6)
n1 += ((self.rd_reg(self.R_HS) & self.N1_H_MASK)<<2)
return n1+1
def get_hs_div(self):
return self.HS_DIV[((self.rd_reg(self.R_HS))>>5)]
def set_rfreq(self, freq):
self.wr_reg(self.R_RFERQ0, (freq & 0xFF))
self.wr_reg(self.R_RFERQ1, ((freq>>8) & 0xFF))
self.wr_reg(self.R_RFERQ2, ((freq>>16) & 0xFF))
self.wr_reg(self.R_RFERQ3, ((freq>>24) & 0xFF))
reg = self.rd_reg(self.R_RFERQ4)
self.wr_reg(self.R_RFERQ4, (((freq>>32) & self.RFREQ4_MASK) | (reg & self.N1_L_MASK)))
def set_hs_div(self, div):
reg = self.rd_reg(self.R_HS)
self.wr_reg(self.R_HS, ((div<<5) | (reg & self.N1_H_MASK)))
def set_n1_div(self, div):
reg = self.rd_reg(self.R_HS)
self.wr_reg(self.R_HS, ((div>>2) | (reg & self.HS_DIV_MASK)))
reg = self.rd_reg(self.R_RFREQ4)
self.wr_reg(self.R_RFREQ4, (((div & self.N1_L_MASK)<<6) | (reg & self.RFREQ4_MASK)))
def freeze_m(self):
reg = self.rd_reg(self.R_RFMC) | self.RFMC_FREEZE_M
self.wr_reg(self.R_RFMC, reg)
def unfreeze_m(self):
reg = self.rd_reg(self.R_RFMC) & ~(self.RFMC_FREEZE_M)
self.wr_reg(self.R_RFMC, reg)
def freeze_dco(self):
self.wr_reg(self.R_RDCO, self.FDCO_FREEZE_DCO)
def unfreeze_dco(self):
self.wr_reg(self.R_RDCO, 0)
def reset_reg(self):
reg = self.rd_reg(self.R_RFMC) | self.RFMC_RST
self.wr_reg(self.R_RFMC, reg)
def recall_nvm(self):
reg = self.rd_reg(self.R_RFMC) | self.RFMC_RECALL
self.wr_reg(self.R_RFMC, reg)
def get_raw_config(self):
config = []
config.append(self.rd_reg(self.R_HS))
config.append(self.rd_reg(self.R_RFREQ4))
config.append(self.rd_reg(self.R_RFREQ3))
config.append(self.rd_reg(self.R_RFREQ2))
config.append(self.rd_reg(self.R_RFREQ1))
config.append(self.rd_reg(self.R_RFREQ0))
return config
# For Si571 only !
def freeze_vcadc(self):
reg = self.rd_reg(self.R_RFMC) | self.RFMC_FREEZE_VCADC
self.wr_reg(self.R_RFMC, reg)
def unfreeze_vcadc(self):
reg = self.rd_reg(self.R_RFMC) & ~(self.RFMC_FREEZE_VCADC)
self.wr_reg(self.R_RFMC, reg)
#!/usr/bin/python
import sys
import rr
import time
class COpenCoresSPI:
R_RX = [0x00, 0x04, 0x08, 0x0C]
R_TX = [0x00, 0x04, 0x08, 0x0C]
R_CTRL = 0x10
R_DIV = 0x14
R_SS = 0x18
LGH_MASK = (0x7F)
CTRL_GO = (1<<8)
CTRL_BSY = (1<<8)
CTRL_RXNEG = (1<<9)
CTRL_TXNEG = (1<<10)
CTRL_LSB = (1<<11)
CTRL_IE = (1<<12)
CTRL_ASS = (1<<13)
DIV_MASK = (0xFFFF)
SS_SEL = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40]
conf = 0x0
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
return self.bus.iread(0, self.base_addr + addr, 4)
def __init__(self, bus, base_addr, divider):
self.bus = bus;
self.base_addr = base_addr;
self.wr_reg(self.R_DIV, (divider & self.DIV_MASK));
# default configuration
self.conf = self.CTRL_ASS | self.CTRL_TXNEG
def wait_busy(self):
while(self.rd_reg(self.R_CTRL) & self.CTRL_BSY):
pass
def config(self, ass, rx_neg, tx_neg, lsb, ie):
self.conf = 0
if(ass):
self.conf |= self.CTRL_ASS
if(tx_neg):
self.conf |= self.CTRL_TXNEG
if(rx_neg):
self.conf |= self.CTRL_RXNEG
if(lsb):
self.conf |= self.CTRL_LSB
if(ie):
self.conf |= self.CTRL_IE
# slave = slave number (0 to 7)
# data = byte data array to send, in case if read fill with dummy data of the right size
def transaction(self, slave, data):
txrx = [0x00000000, 0x00000000, 0x00000000, 0x00000000]
for i in range(0,len(data)):
txrx[i/4] += (data[i]<<((i%4)*8))
#print("tx[%d]=%.8X data[%d]=%.2X") %(i/4,txrx[i/4],i,data[i])
for i in range(0, len(txrx)):
self.wr_reg(self.R_TX[i], txrx[i])
#print('data length: 0x%X')%len(data)
self.wr_reg(self.R_SS, self.SS_SEL[slave])
self.wr_reg(self.R_CTRL, (self.LGH_MASK & (len(data)<<3)) | self.CTRL_GO | self.conf)
self.wait_busy()
for i in range(0, len(txrx)):
txrx[i] = self.rd_reg(self.R_RX[i])
#print("rx[%d]=%.8X") %(i,txrx[i])
return txrx
#gennum = rr.Gennum();
#spi = COpenCoresSPI(gennum, 0x80000, 500);
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