Commit 17dd79cf authored by Andrey Filippov's avatar Andrey Filippov

Merge branch 'master' of git@git.elphel.com:Elphel/x393.git

parents 5a9a6342 cca9678b
......@@ -3,7 +3,7 @@ from __future__ import print_function
'''
# Copyright (C) 2015, Elphel.inc.
# Class to control 10393 sensor-to-memory channel (including histograms)
# Class to control 10393 sensor-to-memory channel (including histograms)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
......@@ -42,6 +42,9 @@ import x393_utils
import time
import vrlg
import x393_mcntrl
import subprocess
#import x393_sens_cmprs
SENSOR_INTERFACE_PARALLEL = "PAR12"
SENSOR_INTERFACE_HISPI = "HISPI"
......@@ -60,7 +63,7 @@ class X393Sensor(object):
self.x393_mem= X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks= x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode)
self.x393_utils= x393_utils.X393Utils(debug_mode,dry_mode, saveFileName) # should not overwrite save file path
try:
self.verbose=vrlg.VERBOSE
except:
......@@ -73,7 +76,7 @@ class X393Sensor(object):
if self.DRY_MODE is True:
return SENSOR_INTERFACE_PARALLEL
return (SENSOR_INTERFACE_PARALLEL, SENSOR_INTERFACE_HISPI)[self.x393_axi_tasks.read_status(address=0xfe)] # "PAR12" , "HISPI"
def program_status_sensor_i2c( self,
num_sensor,
mode, # input [1:0] mode;
......@@ -85,7 +88,7 @@ class X393Sensor(object):
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
3: auto, inc sequence number
3: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
try:
......@@ -114,7 +117,7 @@ class X393Sensor(object):
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
3: auto, inc sequence number
3: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
try:
......@@ -132,7 +135,7 @@ class X393Sensor(object):
vrlg.SENSIO_STATUS,
mode,
seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
def get_status_sensor_io ( self,
num_sensor="All"):
"""
......@@ -149,7 +152,7 @@ class X393Sensor(object):
except:
pass
return self.x393_axi_tasks.read_status(
address=(vrlg.SENSI2C_STATUS_REG_BASE + num_sensor * vrlg.SENSI2C_STATUS_REG_INC + vrlg.SENSIO_STATUS_REG_REL))
address=(vrlg.SENSI2C_STATUS_REG_BASE + num_sensor * vrlg.SENSI2C_STATUS_REG_INC + vrlg.SENSIO_STATUS_REG_REL))
def print_status_sensor_io (self,
num_sensor="All"):
......@@ -168,27 +171,27 @@ class X393Sensor(object):
status= self.get_status_sensor_io(num_sensor)
print ("print_status_sensor_io(%d):"%(num_sensor))
#last_in_line_1cyc_mclk, dout_valid_1cyc_mclk
"""
print (" last_in_line_1cyc_mclk = %d"%((status>>23) & 1))
print (" dout_valid_1cyc_mclk = %d"%((status>>22) & 1))
print (" alive_hist0_gr = %d"%((status>>21) & 1))
print (" alive_hist0_rq = %d"%((status>>20) & 1))
print (" sof_out_mclk = %d"%((status>>19) & 1))
print (" eof_mclk = %d"%((status>>18) & 1))
print (" sof_mclk = %d"%((status>>17) & 1))
"""
print (" last_in_line_1cyc_mclk = %d"%((status>>23) & 1))
print (" dout_valid_1cyc_mclk = %d"%((status>>22) & 1))
print (" alive_hist0_gr = %d"%((status>>21) & 1))
print (" alive_hist0_rq = %d"%((status>>20) & 1))
print (" sof_out_mclk = %d"%((status>>19) & 1))
print (" eof_mclk = %d"%((status>>18) & 1))
print (" sof_mclk = %d"%((status>>17) & 1))
print (" sol_mclk = %d"%((status>>16) & 1))
"""
"""
#Folowing 5 bits may be just temporarily available
#Folowing 5 bits may be just temporarily available
print (" irst = %d"%((status>>20) & 1))
print ("async_prst_with_sens_mrst = %d"%((status>>19) & 1))
print (" imrst = %d"%((status>>18) & 1))
print (" rst_mmcm = %d"%((status>>17) & 1))
print (" pxd_out_pre[1] = %d"%((status>>16) & 1))
"""
print (" shifted TDO %d"%((status>>16) & 0xff))
print (" vact_alive = %d"%((status>>15) & 1))
print (" hact_ext_alive = %d"%((status>>14) & 1))
# print (" hact_alive = %d"%((status>>13) & 1))
......@@ -219,7 +222,7 @@ class X393Sensor(object):
except:
pass
return self.x393_axi_tasks.read_status(
address=(vrlg.SENSI2C_STATUS_REG_BASE + num_sensor * vrlg.SENSI2C_STATUS_REG_INC + vrlg.SENSI2C_STATUS_REG_REL))
address=(vrlg.SENSI2C_STATUS_REG_BASE + num_sensor * vrlg.SENSI2C_STATUS_REG_INC + vrlg.SENSI2C_STATUS_REG_REL))
def print_status_sensor_i2c (self,
num_sensor="All"):
......@@ -245,7 +248,7 @@ class X393Sensor(object):
print (" i2c_fifo_lsb = %d"%((status>> 9) & 1))
print (" i2c_fifo_nempty = %d"%((status>> 8) & 1))
print (" i2c_fifo_dout = %d"%((status>> 0) & 0xff))
print (" sda_in = %d"%((status>>25) & 1))
print (" scl_in = %d"%((status>>24) & 1))
print (" seq = %d"%((status>>26) & 0x3f))
......@@ -253,15 +256,15 @@ class X393Sensor(object):
# Functions used by sensor-related tasks
def func_sensor_mode (self,
hist_en = None,
hist_nrst = None,
chn_en = None,
hist_nrst = None,
chn_en = None,
bits16 = None):
"""
Combine parameters into sensor mode control word
@param hist_en - bit mask to enable histogram sub-modules, when 0 - disable after processing
the started frame
@param hist_nrst - bit mask to immediately reset histogram sub-module (if 0)
@param chn_en - enable sensor channel (False - reset)
@param hist_nrst - bit mask to immediately reset histogram sub-module (if 0)
@param chn_en - enable sensor channel (False - reset)
@param bits16) - True - 16 bpp mode, false - 8 bpp mode (bypass gamma). Gamma-processed data
is still used for histograms
@return: sensor mode control word
......@@ -271,18 +274,18 @@ class X393Sensor(object):
rslt |= (hist_en & 0xf) << vrlg.SENSOR_HIST_EN_BITS
rslt |= (hist_nrst & 0xf) << vrlg.SENSOR_HIST_NRST_BITS
rslt |= 1 << vrlg.SENSOR_HIST_BITS_SET;
if not chn_en is None:
if not chn_en is None:
rslt |= ((0,1)[chn_en]) << vrlg.SENSOR_CHN_EN_BIT
rslt |= 1 << vrlg.SENSOR_CHN_EN_BIT_SET
if not bits16 is None:
if not bits16 is None:
rslt |= ((0,1)[bits16]) << vrlg.SENSOR_16BIT_BIT
rslt |= 1 << vrlg.SENSOR_16BIT_BIT_SET
return rslt
def func_sensor_i2c_command (self,
rst_cmd = False,
run_cmd = None,
active_sda = None,
active_sda = None,
early_release_0 = None,
advance_FIFO = None,
sda = None,
......@@ -292,7 +295,7 @@ class X393Sensor(object):
"""
@param rst_cmd - reset all FIFO (takes 16 clock pulses), also - stops i2c until run command
@param run_cmd - True - run i2c, False - stop i2c (needed before software i2c), None - no change
@param active_sda - pull-up SDA line during second half of SCL=0, when needed and possible
@param active_sda - pull-up SDA line during second half of SCL=0, when needed and possible
@param early_release_0 - release SDA=0 immediately after the end of SCL=1 (SDA hold will be provided by week pullup)
@param advance_FIFO - advance i2c read FIFO
@param sda - control SDA line (stopped mode only): I<nput>, L<ow> or 0, High or 1
......@@ -324,11 +327,11 @@ class X393Sensor(object):
return 2
else:
return 3
if verbose>1:
print ("func_sensor_i2c_command(): rst_cmd= ",rst_cmd,", run_cmd=",run_cmd,", active_sda = ",active_sda,", early_release_0 = ",early_release_0,
", sda=",sda,", scl=",scl)
rslt = 0
rslt |= (0,1)[rst_cmd] << vrlg.SENSI2C_CMD_RESET
if not run_cmd is None:
......@@ -343,28 +346,28 @@ class X393Sensor(object):
if not use_eof is None:
rslt |= 1 << (vrlg.SENSI2C_CMD_USE_EOF + 1)
rslt |= (0,1)[use_eof] << (vrlg.SENSI2C_CMD_USE_EOF)
rslt |= parse_sda_scl(sda) << vrlg.SENSI2C_CMD_SOFT_SDA
rslt |= parse_sda_scl(scl) << vrlg.SENSI2C_CMD_SOFT_SCL
rslt |= parse_sda_scl(sda) << vrlg.SENSI2C_CMD_SOFT_SDA
rslt |= parse_sda_scl(scl) << vrlg.SENSI2C_CMD_SOFT_SCL
if verbose>0:
print (" => 0x%x"%(rslt))
return rslt
return rslt
def func_sensor_i2c_table_reg_wr (self,
slave_addr,
rah,
num_bytes,
num_bytes,
bit_delay,
verbose = 1):
"""
@param slave_addr - 7-bit i2c slave address
@param rah - register address high byte (bits [15:8]) optionally used for register write commands
@param num_bytes - number of bytes to send (including register address bytes) 1..10
@param num_bytes - number of bytes to send (including register address bytes) 1..10
@param bit_delay - number of mclk clock cycle in 1/4 of the SCL period
@param verbose - verbose level
@return combined table data word.
"""
"""
if verbose>1:
print ("func_sensor_i2c_table_reg_wr(): slave_addr= ",slave_addr,", rah=",rah,", num_bytes = ",num_bytes,", bit_delay = ",bit_delay)
rslt = 0
......@@ -372,7 +375,7 @@ class X393Sensor(object):
rslt |= (rah & ((1 << vrlg.SENSI2C_TBL_RAH_BITS) - 1)) << vrlg.SENSI2C_TBL_RAH
rslt |= (num_bytes & ((1 << vrlg.SENSI2C_TBL_NBWR_BITS) - 1)) << vrlg.SENSI2C_TBL_NBWR
rslt |= (bit_delay & ((1 << vrlg.SENSI2C_TBL_DLY_BITS) - 1)) << vrlg.SENSI2C_TBL_DLY
return rslt
return rslt
def func_sensor_i2c_table_reg_rd (self,
two_byte_addr,
......@@ -385,7 +388,7 @@ class X393Sensor(object):
@param bit_delay - number of mclk clock cycle in 1/4 of the SCL period
@param verbose - verbose level
@return combined table data word.
"""
"""
if verbose>0:
print ("func_sensor_i2c_table_reg_rd(): two_byte_addr= ",two_byte_addr,", num_bytes_rd=",num_bytes_rd,", bit_delay = ",bit_delay)
rslt = 0
......@@ -395,7 +398,7 @@ class X393Sensor(object):
rslt |= (0,1)[two_byte_addr] << vrlg.SENSI2C_TBL_NABRD
rslt |= (num_bytes_rd & ((1 << vrlg.SENSI2C_TBL_NBRD_BITS) - 1)) << vrlg.SENSI2C_TBL_NBRD
rslt |= (bit_delay & ((1 << vrlg.SENSI2C_TBL_DLY_BITS) - 1)) << vrlg.SENSI2C_TBL_DLY
return rslt
return rslt
def func_sensor_io_ctl (self,
mrst = None,
......@@ -406,13 +409,13 @@ class X393Sensor(object):
set_delays = False,
quadrants = None):
"""
Combine sensor I/O control parameters into a control word
Combine sensor I/O control parameters into a control word
@param mrst - True - activate MRST signal (low), False - deactivate MRST (high), None - no change
@param arst - True - activate ARST signal (low), False - deactivate ARST (high), None - no change
@param aro - True - activate ARO signal (low), False - deactivate ARO (high), None - no change
@param mmcm_rst - True - activate MMCM reset, False - deactivate MMCM reset, None - no change (needed after clock change/interruption)
@param clk_sel - True - use pixel clock from the sensor, False - use internal clock (provided to the sensor), None - no chnage
@param set_delays - (self-clearing) load all pre-programmed delays for the sensor pad inputs
@param set_delays - (self-clearing) load all pre-programmed delays for the sensor pad inputs
@param quadrants - 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] [6] - extra hact delay by 1 pixel (7'h01), None - no change
@return sensor i/o control word
"""
......@@ -447,7 +450,7 @@ class X393Sensor(object):
@param tck = False - set TCK low, True - set TCK high, None - keep previous value
@param tms = False - set TMS low, True - set TMS high, None - keep previous value
@param tdi = False - set TDI low, True - set TDI high, None - keep previous value
@return combined control word
@return combined control word
"""
rslt = 0
if not pgmen is None:
......@@ -480,7 +483,7 @@ class X393Sensor(object):
if not bayer is None:
rslt |= (bayer & 3) << vrlg.SENS_GAMMA_MODE_BAYER
rslt |= 1 << vrlg.SENS_GAMMA_MODE_BAYER_SET
if not table_page is None:
rslt |= (0,1)[table_page] << vrlg.SENS_GAMMA_MODE_PAGE
rslt |= 1 << vrlg.SENS_GAMMA_MODE_PAGE_SET
......@@ -488,11 +491,11 @@ class X393Sensor(object):
if not en_input is None:
rslt |= (0,1)[en_input] << vrlg.SENS_GAMMA_MODE_EN
rslt |= 1 << vrlg.SENS_GAMMA_MODE_EN_SET
if not repet_mode is None:
rslt |= (0,1)[repet_mode] << vrlg.SENS_GAMMA_MODE_REPET
rslt |= 1 << vrlg.SENS_GAMMA_MODE_REPET_SET
rslt |= (0,1)[trig] << vrlg.SENS_GAMMA_MODE_TRIG
return rslt
......@@ -511,20 +514,20 @@ class X393Sensor(object):
@return status register address for I/O for selected sensor port
"""
return (vrlg.SENSI2C_STATUS_REG_BASE + num_sensor * vrlg.SENSI2C_STATUS_REG_INC + vrlg.SENSIO_STATUS_REG_REL);
def set_sensor_mode (self,
num_sensor,
hist_en = None,
hist_nrst = None,
chn_en = None,
hist_nrst = None,
chn_en = None,
bits16 = None):
"""
Set sensor mode
@param num_sensor - sensor port number (0..3)
@param hist_en - bit mask to enable histogram sub-modules, when 0 - disable after processing
the started frame
@param hist_nrst - bit mask to immediately reset histogram sub-module (if 0)
@param chn_en - enable sensor channel (False - reset)
@param hist_nrst - bit mask to immediately reset histogram sub-module (if 0)
@param chn_en - enable sensor channel (False - reset)
@param bits16) - True - 16 bpp mode, false - 8 bpp mode (bypass gamma). Gamma-processed data
is still used for histograms
"""
......@@ -533,29 +536,29 @@ class X393Sensor(object):
for num_sensor in range(4):
self.set_sensor_mode (num_sensor = num_sensor,
hist_en = hist_en,
hist_nrst = hist_nrst,
chn_en = chn_en,
hist_nrst = hist_nrst,
chn_en = chn_en,
bits16 = bits16)
return
except:
pass
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSOR_CTRL_RADDR,
self.func_sensor_mode(
hist_en = hist_en,
hist_nrst = hist_nrst,
chn_en = chn_en,
bits16 = bits16))
def set_sensor_i2c_command (self,
num_sensor,
rst_cmd = False,
run_cmd = None,
active_sda = None,
active_sda = None,
early_release_0 = None,
advance_FIFO = None,
sda = None,
......@@ -566,7 +569,7 @@ class X393Sensor(object):
@param num_sensor - sensor port number (0..3) or all
@param rst_cmd - reset all FIFO (takes 16 clock pulses), also - stops i2c until run command
@param run_cmd - True - run i2c, False - stop i2c (needed before software i2c), None - no change
@param active_sda - pull-up SDA line during second half of SCL=0, when needed and possible
@param active_sda - pull-up SDA line during second half of SCL=0, when needed and possible
@param early_release_0 - release SDA=0 immediately after the end of SCL=1 (SDA hold will be provided by week pullup)
@param advance_FIFO - advance i2c read FIFO
@param sda - control SDA line (stopped mode only): I<nput>, L<ow> or 0, High or 1
......@@ -582,19 +585,19 @@ class X393Sensor(object):
self.set_sensor_i2c_command (num_sensor,
rst_cmd = rst_cmd,
run_cmd = run_cmd,
active_sda = active_sda,
active_sda = active_sda,
early_release_0 = early_release_0,
advance_FIFO = advance_FIFO,
sda = sda,
scl = scl,
use_eof = use_eof,
use_eof = use_eof,
verbose = verbose)
return
except:
pass
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSI2C_CTRL_RADDR,
self.func_sensor_i2c_command(
rst_cmd = rst_cmd,
......@@ -612,7 +615,7 @@ class X393Sensor(object):
page,
slave_addr,
rah,
num_bytes,
num_bytes,
bit_delay,
verbose = 1):
"""
......@@ -621,7 +624,7 @@ class X393Sensor(object):
@param page - 1 byte table index (later provided as high byte of the 32-bit command)
@param slave_addr - 7-bit i2c slave address
@param rah - register address high byte (bits [15:8]) optionally used for register write commands
@param num_bytes - number of bytes to send (including register address bytes) 1..10
@param num_bytes - number of bytes to send (including register address bytes) 1..10
@param bit_delay - number of mclk clock cycle in 1/4 of the SCL period
@param verbose - verbose level
"""
......@@ -629,9 +632,9 @@ class X393Sensor(object):
td = (1 << vrlg.SENSI2C_CMD_TABLE) | self.func_sensor_i2c_table_reg_wr(
slave_addr = slave_addr,
rah = rah,
num_bytes = num_bytes,
num_bytes = num_bytes,
bit_delay = bit_delay,
verbose = verbose)
verbose = verbose)
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSI2C_CTRL_RADDR, ta)
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSI2C_CTRL_RADDR, td)
......@@ -657,7 +660,7 @@ class X393Sensor(object):
two_byte_addr = two_byte_addr,
num_bytes_rd = num_bytes_rd,
bit_delay = bit_delay,
verbose = verbose)
verbose = verbose)
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSI2C_CTRL_RADDR, ta)
self.x393_axi_tasks.write_control_register(vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC + vrlg.SENSI2C_CTRL_RADDR, td)
if verbose > 1:
......@@ -693,12 +696,12 @@ class X393Sensor(object):
after the slave address and optional high address byte other bytes are sent in descending order (LSB- last).
If less than 4 bytes are programmed in the table the high bytes (starting with the one from the table) are
skipped.
If more than 4 bytes are programmed in the table for the page (high byte), one or two next 32-bit words
If more than 4 bytes are programmed in the table for the page (high byte), one or two next 32-bit words
bypass the index table and all 4 bytes are considered payload ones. If less than 4 extra bytes are to be
sent for such extra word, only the lower bytes are sent.
2 - register read: index page, slave address (8-bit, with lower bit 0) and one or 2 address bytes (as programmed
in the table. Slave address is always in byte 2 (bits 23:16), byte1 (high register address) is skipped if
read address in the table is programmed to be a single-byte one
read address in the table is programmed to be a single-byte one
"""
try:
if (num_sensor == all) or (num_sensor[0].upper() == "A"): #all is a built-in function
......@@ -759,7 +762,7 @@ class X393Sensor(object):
if len(rslt) == num_bytes:
break # read all that was requested (num_bytes == None will not get here)
return rslt
def print_sensor_i2c (self,
num_sensor,
reg_addr,
......@@ -783,7 +786,7 @@ class X393Sensor(object):
for b in dl:
d = (d << 8) | (b & 0xff)
fmt="FIFO contained %d bytes i2c data = 0x%%0%dx"%(len(dl),len(dl*2))
print (fmt%(d))
print (fmt%(d))
#create and send i2c command in ASAP mode:
i2c_cmd = ((indx & 0xff) << 24) | (sa7 <<17) | (reg_addr & 0xffff)
#write_sensor_i2c 0 1 0 0x91900004
......@@ -793,8 +796,8 @@ class X393Sensor(object):
data = i2c_cmd)
time.sleep(0.05) # We do not know how many bytes are expected, so just wait long enough and hope all bytes are in fifo already
dl = self.read_sensor_i2c (num_sensor = num_sensor,
num_bytes = None,
verbose = verbose)
......@@ -802,9 +805,9 @@ class X393Sensor(object):
d = 0
for b in dl:
d = (d << 8) | (b & 0xff)
if verbose > 0:
if verbose > 0:
fmt="i2c data[0x%02x:0x%x] = 0x%%0%dx"%(sa7,reg_addr,len(dl)*2)
print (fmt%(d))
print (fmt%(d))
return d
def set_sensor_flipXY(self,
......@@ -824,14 +827,14 @@ class X393Sensor(object):
flip_x = False
if flip_y is None:
flip_y = False
if sensorType == "PAR12":
data = (0,0x8000)[flip_y] | (0,0x4000)[flip_x]
data = (0,0x8000)[flip_y] | (0,0x4000)[flip_x]
self.write_sensor_reg16 (num_sensor = num_sensor,
reg_addr16 = 0x9020,
reg_data16 = data)
elif sensorType == "HISPI":
data = (0,0x8000)[flip_y] | (0,0x4000)[flip_x] | 0x41
data = (0,0x8000)[flip_y] | (0,0x4000)[flip_x] | 0x41
self.write_sensor_reg16 (num_sensor = num_sensor,
reg_addr16 = 0x3040,
reg_data16 = data)
......@@ -902,7 +905,7 @@ class X393Sensor(object):
reg_data16 = exposure)
else:
raise ("Unknown sensor type: %s"%(sensorType))
def set_sensor_io_ctl (self,
num_sensor,
mrst = None,
......@@ -913,14 +916,14 @@ class X393Sensor(object):
set_delays = False,
quadrants = None):
"""
Set sensor I/O controls, including I/O signals
Set sensor I/O controls, including I/O signals
@param num_sensor - sensor port number (0..3)
@param mrst - True - activate MRST signal (low), False - deactivate MRST (high), None - no change
@param arst - True - activate ARST signal (low), False - deactivate ARST (high), None - no change
@param aro - True - activate ARO signal (low), False - deactivate ARO (high), None - no change
@param mmcm_rst - True - activate MMCM reset, False - deactivate MMCM reset, None - no change (needed after clock change/interruption)
@param clk_sel - True - use pixel clock from the sensor, False - use internal clock (provided to the sensor), None - no chnage
@param set_delays - (self-clearing) load all pre-programmed delays for the sensor pad inputs
@param set_delays - (self-clearing) load all pre-programmed delays for the sensor pad inputs
@param quadrants - 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] (6'h01), None - no change
"""
try:
......@@ -938,7 +941,7 @@ class X393Sensor(object):
except:
pass
data = self.func_sensor_io_ctl (
mrst = mrst,
arst = arst,
......@@ -947,7 +950,7 @@ class X393Sensor(object):
clk_sel = clk_sel,
set_delays = set_delays,
quadrants = quadrants)
reg_addr = (vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC) + vrlg.SENSIO_RADDR + vrlg.SENSIO_CTRL;
self.x393_axi_tasks.write_control_register(reg_addr, data)
# TODO: Make one for HiSPi (it is different)
......@@ -965,12 +968,12 @@ class X393Sensor(object):
@param iclk_dly - delay in the input clock line (3 LSB are not used)
@param vact_dly - delay in the VACT line (3 LSB are not used)
@param hact_dly - delay in the HACT line (3 LSB are not used)
@param pxd_dly - list of data line delays (12 elements, 3 LSB are not used)
@param pxd_dly - list of data line delays (12 elements, 3 LSB are not used)
"""
dlys=((pxd_dly[0] & 0xff) | ((pxd_dly[1] & 0xff) << 8) | ((pxd_dly[ 2] & 0xff) << 16) | ((pxd_dly[ 3] & 0xff) << 24),
(pxd_dly[4] & 0xff) | ((pxd_dly[5] & 0xff) << 8) | ((pxd_dly[ 6] & 0xff) << 16) | ((pxd_dly[ 7] & 0xff) << 24),
(pxd_dly[8] & 0xff) | ((pxd_dly[9] & 0xff) << 8) | ((pxd_dly[10] & 0xff) << 16) | ((pxd_dly[11] & 0xff) << 24),
(hact_dly & 0xff) | ((vact_dly & 0xff) << 8) | ((iclk_dly & 0xff) << 16) | ((mmcm_phase & 0xff) << 24))
(hact_dly & 0xff) | ((vact_dly & 0xff) << 8) | ((iclk_dly & 0xff) << 16) | ((mmcm_phase & 0xff) << 24))
reg_addr = (vrlg.SENSOR_GROUP_ADDR + num_sensor * vrlg.SENSOR_BASE_INC) + vrlg.SENSIO_RADDR + vrlg.SENSIO_DELAYS;
self.x393_axi_tasks.write_control_register(reg_addr + 0, dlys[0]) # {pxd3, pxd2, pxd1, pxd0}
self.x393_axi_tasks.write_control_register(reg_addr + 1, dlys[1]) # {pxd7, pxd6, pxd5, pxd4}
......@@ -993,7 +996,7 @@ class X393Sensor(object):
@param lane0_dly - delay in the lane0 (3 LSB are not used) // All 4 lane delays should be set simultaneously
@param lane1_dly - delay in the lane1 (3 LSB are not used)
@param lane2_dly - delay in the lane2 (3 LSB are not used)
@param lane3_dly - delay in the lane3 (3 LSB are not used))
@param lane3_dly - delay in the lane3 (3 LSB are not used))
"""
try:
if (num_sensor == all) or (num_sensor[0].upper() == "A"): #all is a built-in function
......@@ -1012,10 +1015,10 @@ class X393Sensor(object):
dlys=(lane0_dly & 0xff) | ((lane1_dly & 0xff) << 8) | ((lane2_dly & 0xff) << 16) | ((lane3_dly & 0xff) << 24)
self.x393_axi_tasks.write_control_register(reg_addr + 2, dlys)
except:
pass
pass
if not mmcm_phase is None:
self.x393_axi_tasks.write_control_register(reg_addr + 3, mmcm_phase & 0xff)
def set_sensor_hispi_lanes(self,
num_sensor,
lane0 = 0,
......@@ -1076,23 +1079,23 @@ class X393Sensor(object):
# mode = 1, # input [1:0] mode;
# seq_num = seq_num) # input [5:0] seq_num;
# return seq_num
def jtag_get_tdo(self, chn):
seq_num = ((self.get_status_sensor_io(num_sensor = chn) >> 26) + 1) & 0x3f
self.program_status_sensor_io(num_sensor = chn,
mode = 1, # input [1:0] mode;
seq_num = seq_num) # input [5:0] seq_num;
for _ in range(10):
stat = self.get_status_sensor_io(num_sensor = chn)
if seq_num == ((stat >> 26) & 0x3f):
break
break
else:
print ("wait_sensio_status(): Failed to get seq_num== 0x%x, current is 0x%x"%(seq_num, (stat >> 26) & 0x3f))
return (stat >> 25) & 1
return (stat >> 25) & 1
def jtag_send(self, chn, tms, ln, d):
i = ln & 7
if (i == 0):
......@@ -1103,7 +1106,7 @@ class X393Sensor(object):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 0,
tck = 0,
tms = tms,
tdi = ((d << 1) >> 8) & 1)
d <<= 1
......@@ -1111,25 +1114,25 @@ class X393Sensor(object):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 1,
tck = 1,
tms = None,
tdi = None)
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 0,
tck = 0,
tms = None,
tdi = None)
i -= 1
return r
def jtag_write_bits (self,
chn,
buf, # data to write
ln, # number of bits to write
# check, # compare readback data with previously written, abort on mismatch
last): # output last bit with TMS=1
# prev = None): # if null - don't use
# prev = None): # if null - don't use
rbuf = []
r = 0
for d0 in buf:
......@@ -1139,7 +1142,7 @@ class X393Sensor(object):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 0,
tck = 0,
tms = (0,1)[(ln == 1) and last],
tdi = ((d << 1) >> 8) & 1)
d <<= 1
......@@ -1147,27 +1150,27 @@ class X393Sensor(object):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 1,
tck = 1,
tms = None,
tdi = None)
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = None,
tck = 0,
tck = 0,
tms = None,
tdi = None)
else:
r <<= 1
ln -= 1
ln -= 1
rbuf.append(r & 0xff)
return rbuf
def jtag_set_pgm_mode(self,chn,en):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = en,
prog = None,
tck = 0,
tck = 0,
tms = None,
tdi = None)
......@@ -1175,11 +1178,11 @@ class X393Sensor(object):
self.set_sensor_io_jtag (num_sensor = chn,
pgmen = None,
prog = en,
tck = 0,
tck = 0,
tms = None,
tdi = None)
def JTAG_openChannel (self, chn):
self.jtag_set_pgm_mode (chn, 1);
self.jtag_set_pgm (chn, 1)
......@@ -1204,8 +1207,8 @@ class X393Sensor(object):
last = 1)
self.jtag_send(chn, 1, 1, 0 ) #step 9 - set UPDATE-DR state
return rbuf
# /dev/sfpgabscan0
def readbscan(self, filename):
......@@ -1214,8 +1217,8 @@ class X393Sensor(object):
jtag.write(ffs)
jtag.seek (0,0)
boundary= jtag.read(97)
return boundary
return boundary
def checkSclSda(self, chn, verbose = 1):
'''
Check which board is connected to the sensor board
......@@ -1225,20 +1228,20 @@ class X393Sensor(object):
'''
def print_i2c(chn):
self.program_status_sensor_i2c(num_sensor = chn, mode = 1, seq_num = 0)
status= self.get_status_sensor_i2c(num_sensor = chn)
status= self.get_status_sensor_i2c(num_sensor = chn)
sda_in =(status>>25) & 1
scl_in =(status>>24) & 1
print ("chn = %d, scl = %d, sda = %d"%(chn,scl_in, sda_in))
def print_bv(chn, boundary, value, key):
def print_bv(chn, boundary, value, key):
self.program_status_sensor_i2c(num_sensor = chn, mode = 1, seq_num = 0)
status= self.get_status_sensor_i2c(num_sensor = chn)
status= self.get_status_sensor_i2c(num_sensor = chn)
sda_in =(status>>25) & 1
scl_in =(status>>24) & 1
print ("%d: sda = %d, bit number SDA = %d, pin value SDA = %d"%(key, sda_in, value['sda'], (((ord(boundary[value['sda'] >> 3]) >> (7 -(value['sda'] & 7))) &1)) ))
print ("%d: scl = %d, bit number SCL = %d, pin value SCL = %d"%(key, scl_in, value['scl'], (((ord(boundary[value['scl'] >> 3]) >> (7 -(value['scl'] & 7))) &1)) ))
boards = [{'model':'10347', 'scl': 241,'sda': 199}, #// E4, C1
{'model':'10359', 'scl': 280,'sda': 296}] #// H6, J5
bscan_path=('/dev/sfpgabscan%d'%(chn))
......@@ -1248,7 +1251,7 @@ class X393Sensor(object):