Commit a8ec8a03 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

sw: Added thermometer test script

parent c9d6d24b
......@@ -8,7 +8,7 @@ all:
mkdir -p pts-conv-ttl-rs485/lib
cp -r shell/ pts-conv-ttl-rs485/
mv pts-conv-ttl-rs485/shell/program pts-conv-ttl-rs485/boot
wget -P pts-conv-ttl-rs485/boot http://www.ohwr.org/attachments/download/3640/pts.bit
wget -P pts-conv-ttl-rs485/boot http://www.ohwr.org/attachments/download/3642/pts.bit
cp python/pts.py pts-conv-ttl-rs485
cp python/jpts.py pts-conv-ttl-rs485
cp python/vv_pts.py pts-conv-ttl-rs485/lib/
......@@ -20,10 +20,12 @@ all:
sed -i "s/ELMASLOT = 4/ELMASLOT = $(ELMASLOT)/" pts-conv-ttl-rs485/lib/ptsdefine.py
cp python/leds.py pts-conv-ttl-rs485/tests/
cp python/therm_id.py pts-conv-ttl-rs485/tests/
cp python/ttl_pulse_switch.py pts-conv-ttl-rs485/tests/
ln -s tests/leds.py pts-conv-ttl-rs485/test01.py
ln -s tests/ttl_pulse_switch.py pts-conv-ttl-rs485/test02.py
ln -s tests/therm_id.py pts-conv-ttl-rs485/test02.py
ln -s tests/ttl_pulse_switch.py pts-conv-ttl-rs485/test03.py
clean:
rm -rf pts-conv-ttl-rs485
......
##_______________________________________________________________________________________________
##
## CONV-TTL-RS485 PTS
##
## CERN,BE/CO-HT
##_______________________________________________________________________________________________
##
##------------------------------------------------------------------------------------------------
##
## CONV-TTL-RS485 TEMPID test
##
##------------------------------------------------------------------------------------------------
##
## Description Testing of the DS18B20 thermometer chip (ICxxx) on the CONV-TTL-RS-485 . The
## firmware loaded to the FPGA implements the interface for the communication between
## the SKT bus and the one wire of the DS18B20; this interface a one wire Wishbone
## master, running on a 20 MHz system clock.
##
## The family code of the DS18B20 is x28, predefined in the part number.
##
## The test reads the unique ID and the temperature and checks if the received
## values are within reasonable limits.
##
## Authors Julian Lewis (Julian.Lewis@cern.ch)
## Theodor Stana (t.stana@cern.ch)
## Website http://www.ohwr.org/projects/conv-ttl-rs485
## Date 31/10/2014
##------------------------------------------------------------------------------------------------
##
##------------------------------------------------------------------------------------------------
## GNU LESSER GENERAL PUBLIC LICENSE
## ------------------------------------
## This source file is free software; you can redistribute it and/or modify it under the terms of
## the GNU Lesser General Public License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
## This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
## without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
## See the GNU Lesser General Public License for more details.
## You should have received a copy of the GNU Lesser General Public License along with this
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
##-------------------------------------------------------------------------------------------------
##-------------------------------------------------------------------------------------------------
## Import
##-------------------------------------------------------------------------------------------------
# Import system modules
import sys
sys.path.append("../lib/")
import time
import os
# Import common modules
from ctypes import *
from ptsexcept import *
from vv_pts import *
from ptsdefine import *
##-------------------------------------------------------------------------------------------------
## One Wire class --
##-------------------------------------------------------------------------------------------------
class COpenCoresOneWire:
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.vv_write(self.base + addr,val)
def rd_reg(self,addr):
return self.bus.vv_read(self.base + addr)
def __init__(self, bus, base, clk_div_nor, clk_div_ovd):
self.bus = bus
self.base = base
data = ((clk_div_nor & self.CDR_NOR_MSK) | ((clk_div_ovd<<self.CDR_OVD_OFS) & self.CDR_OVD_MSK))
self.wr_reg(self.R_CDR, data)
def reset(self, port):
data = ((port<<self.CSR_SEL_OFS) & self.CSR_SEL_MSK) | self.CSR_CYC_MSK | self.CSR_RST_MSK
self.wr_reg(self.R_CSR, data)
tmo = 100
while(self.rd_reg(self.R_CSR) & self.CSR_CYC_MSK):
tmo = tmo -1
if tmo <= 0:
msg = "ERROR: TempID ICxxx: Not responding"
raise PtsError(msg)
reg = self.rd_reg(self.R_CSR)
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)
tmo = 100
while(self.rd_reg(self.R_CSR) & self.CSR_CYC_MSK):
tmo = tmo -1
if tmo <= 0:
msg = "ERROR: TempID ICxxx: Not responding"
raise PtsError(msg)
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
##-------------------------------------------------------------------------------------------------
## DS18B20 class --
##-------------------------------------------------------------------------------------------------
class CDS18B20:
ROM_SEARCH = 0xF0
ROM_READ = 0x33
ROM_MATCH = 0x55
ROM_SKIP = 0xCC
ROM_ALARM_SEARCH = 0xEC
CONVERT_TEMP = 0x44
WRITE_SCRATCHPAD = 0x4E
READ_SCRATCHPAD = 0xBE
COPY_SCRATCHPAD = 0x48
RECALL_EEPROM = 0xB8
READ_POWER_SUPPLY = 0xB4
def __init__(self, onewire, port):
self.onewire = onewire
self.port = port
def read_serial_number(self):
if(1 != self.onewire.reset(self.port)):
msg = "ERROR: TempID ICxxx: Not responding"
raise PtsError(msg)
else:
err = self.onewire.write_byte(self.port, self.ROM_READ)
if err != 0:
msg = "ERROR: TempID ICxxx: Write failed"
raise PtsError(msg)
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)
return ((crc<<56) | (serial_number<<8) | family_code)
def access(self, serial_number):
if(1 != self.onewire.reset(self.port)):
msg = "ERROR: TempID ICxxx: Not responding"
raise PtsError(msg)
else:
err = self.onewire.write_byte(self.port, self.ROM_MATCH)
block = []
for i in range(8):
block.append(serial_number & 0xFF)
serial_number >>= 8
self.onewire.write_block(self.port, block)
return 0
def read_temp(self, serial_number):
err = self.access(serial_number)
err = self.onewire.write_byte(self.port, self.CONVERT_TEMP)
time.sleep(0.8)
err = self.access(serial_number)
err = self.onewire.write_byte(self.port, self.READ_SCRATCHPAD)
data = self.onewire.read_block(self.port, 9)
temp = (data[1] << 8) | (data[0])
if(temp & 0x1000):
temp = -0x10000 + temp
temp = temp/16.0
return temp
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main(bus,tname,inf,log):
"""
tests : Thermometer ICxxx and unique ID
uses : pts.bit and therm_id.py
"""
FAMILY_CODE = 0x28
pel = PTS_ERROR_LOGGER(inf,log)
try:
# Create bus objects
onewire = COpenCoresOneWire(bus, TEMP_1WIRE_BASE, 99, 19)
ds18b20 = CDS18B20(onewire, 0)
# Reading of unique ID
unique_id = ds18b20.read_serial_number()
if(unique_id == -1):
msg = "ERROR: TempID ICxxx: Unable to read 1-wire thermometer"
pel.set(msg)
else:
inf.write("Unique ID: %.12X\n" % (unique_id))
# Reading of temperature
temp = ds18b20.read_temp(unique_id)
inf.write("Current temperature: %3.3f\n" % temp)
# Cheking if received values are reasonable
if temp < 10.0 or temp > 50.0:
msg = "ERROR: TempID ICxxx: Temperature: %d out of range[10 .. 50oC]" % (temp)
pel.set(msg)
if((unique_id & 0xFF) != FAMILY_CODE):
family_code = unique_id & 0xFF
msg = "ERROR: TempID ICxxx: Invalid family code: 0x%.8X\n" % (family_code)
pel.set(msg)
return pel.get()
except BusException, e:
raise PtsError("SKT Exception: %s" % (e))
except BusWarning, e:
raise PtsError("SKT Warning: %s" % (e))
#finally:
# return pel.get()
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