Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
d9f09d9d
Commit
d9f09d9d
authored
Aug 29, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added more Python modules to control hardware, some bug fixes
parent
b13c86d4
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
879 additions
and
133 deletions
+879
-133
cmprs_afi_mux.v
axi/cmprs_afi_mux.v
+1
-1
mult_saxi_wr.v
axi/mult_saxi_wr.v
+2
-2
jp_channel.v
compressor_jp/jp_channel.v
+1
-1
convert_data_to_params.py
helpers/convert_data_to_params.py
+2
-2
x393_parameters.vh
includes/x393_parameters.vh
+1
-1
test_mcntrl.py
py393/test_mcntrl.py
+21
-16
x393_axi_control_status.py
py393/x393_axi_control_status.py
+0
-79
x393_cmprs.py
py393/x393_cmprs.py
+20
-0
x393_frame_sequencer.py
py393/x393_frame_sequencer.py
+105
-0
x393_gpio.py
py393/x393_gpio.py
+2
-2
x393_mcntrl_adjust.py
py393/x393_mcntrl_adjust.py
+1
-1
x393_mcntrl_membridge.py
py393/x393_mcntrl_membridge.py
+1
-1
x393_pio_sequences.py
py393/x393_pio_sequences.py
+4
-4
x393_sensor.py
py393/x393_sensor.py
+687
-0
rtc393.v
timing/rtc393.v
+1
-1
timing393.v
timing/timing393.v
+1
-1
x393.v
x393.v
+1
-1
x393_testbench02.tf
x393_testbench02.tf
+28
-20
No files found.
axi/cmprs_afi_mux.v
View file @
d9f09d9d
...
...
@@ -45,7 +45,7 @@ each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop),
*/
parameter
CMPRS_AFIMUX_SA_LEN
=
'h8
,
// .. 'hf
/*
27-bit "chunk" addresses and lengths. 1 chunk = 32 bytes, so 27 bit covers all 2^32 add
er
ss range
27-bit "chunk" addresses and lengths. 1 chunk = 32 bytes, so 27 bit covers all 2^32 add
re
ss range
8 .. 11 - per-channel start adddresses,
12 .. 15 - per-channel buffer lengths (will roll over to start address)
(0..3 - start addresses, 4..7 - lengths)
...
...
axi/mult_saxi_wr.v
View file @
d9f09d9d
...
...
@@ -127,7 +127,7 @@ module mult_saxi_wr #(
wire
[
127
:
0
]
data_in
;
wire
[
3
:
0
]
pre_valid
;
reg
[
3
:
0
]
valid
;
reg
[
BRAM_A_WDTH
-
1
:
0
]
buf_wa
;
// multiplexed buffer write add
er
ss
reg
[
BRAM_A_WDTH
-
1
:
0
]
buf_wa
;
// multiplexed buffer write add
re
ss
reg
[
31
:
0
]
buf_wd
;
// multiplexed buffer write data
reg
buf_we
;
// multiplexed buffer write enable
...
...
@@ -136,7 +136,7 @@ module mult_saxi_wr #(
wire
en_out_arb
;
wire
[
1
:
0
]
re_cur_chn
;
reg
[
BRAM_A_WDTH
-
1
:
0
]
buf_ra
;
// multiplexed buffer write add
er
ss
reg
[
BRAM_A_WDTH
-
1
:
0
]
buf_ra
;
// multiplexed buffer write add
re
ss
wire
[
31
:
0
]
inter_buf_data
;
// multiplexed buffer write data
reg
[
2
:
0
]
buf_re
;
// multiplexed buffer write enable
...
...
compressor_jp/jp_channel.v
View file @
d9f09d9d
...
...
@@ -228,7 +228,7 @@ module jp_channel#(
// wire [11:0] buf_ra; // buffer read address (2 MSB - page number)
wire
[
1
:
0
]
buf_rd
;
// buf {regen, re}
wire
[
7
:
0
]
buf_pxd
;
// 8-bit pixel data from the memory buffer
wire
[
11
:
0
]
buf_ra
;
// Memory buffer read add
er
ss
wire
[
11
:
0
]
buf_ra
;
// Memory buffer read add
re
ss
// signals connecting modules: chn_rd_buf_i and ???:
wire
[
7
:
0
]
mb_data_out
;
// Macroblock data out in scanline order
wire
mb_pre_first_out
;
// Macroblock data out strobe - 1 cycle just before data valid
...
...
helpers/convert_data_to_params.py
View file @
d9f09d9d
...
...
@@ -85,8 +85,8 @@ def print_params(data,out_file_name):
print
(
", .INITP_
%02
X (256'h
%064
X)"
%
(
i
,
v
),
file
=
out_file
)
#print ('Number of arguments: %d'%(len(sys.argv)))
#print ('Argument List:%s'%(str(sys.argv)))
with
open
(
sys
.
argv
[
1
])
as
f
ile
:
tokens
=
f
ile
.
read
()
.
split
()
with
open
(
sys
.
argv
[
1
])
as
f
:
tokens
=
f
.
read
()
.
split
()
# print(lines)
#print (lines.split())
values
=
[]
...
...
includes/x393_parameters.vh
View file @
d9f09d9d
...
...
@@ -630,7 +630,7 @@
parameter RTC_ADDR= 'h704, // 'h707
parameter CAMSYNC_ADDR = 'h708, // 'h70f
parameter RTC_STATUS_REG_ADDR = 'h31, // (1 loc) address where status can be read out (currently just sequence # and alternating bit)
parameter RTC_SEC_USEC_ADDR = 'h32, // ..'h33 address where seconds of the snapshot can be read (microseconds - next add
er
ss)
parameter RTC_SEC_USEC_ADDR = 'h32, // ..'h33 address where seconds of the snapshot can be read (microseconds - next add
re
ss)
parameter RTC_MASK = 'h7fc,
parameter CAMSYNC_MASK = 'h7f8,
parameter CAMSYNC_MODE = 'h0,
...
...
py393/test_mcntrl.py
View file @
d9f09d9d
...
...
@@ -62,7 +62,8 @@ import x393_camsync
import
x393_gpio
import
x393_cmprs_afi
import
x393_cmprs
import
x393_frame_sequencer
import
x393_sensor
import
vrlg
__all__
=
[]
__version__
=
0.1
...
...
@@ -328,21 +329,23 @@ USAGE
print
(
"vrlg.VERBOSE__TYPE="
+
str
(
vrlg
.
VERBOSE__TYPE
))
print
(
"vrlg.VERBOSE__RAW="
+
str
(
vrlg
.
VERBOSE__RAW
))
x393mem
=
x393_mem
.
X393Mem
(
verbose
,
args
.
simulated
)
#add dry run parameter
x393utils
=
x393_utils
.
X393Utils
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393tasks
=
x393_axi_control_status
.
X393AxiControlStatus
(
verbose
,
args
.
simulated
)
x393Pio
=
x393_pio_sequences
.
X393PIOSequences
(
verbose
,
args
.
simulated
)
x393Timing
=
x393_mcntrl_timing
.
X393McntrlTiming
(
verbose
,
args
.
simulated
)
x393Buffers
=
x393_mcntrl_buffers
.
X393McntrlBuffers
(
verbose
,
args
.
simulated
)
x393Tests
=
x393_mcntrl_tests
.
X393McntrlTests
(
verbose
,
args
.
simulated
)
x393Eyepatterns
=
x393_mcntrl_eyepatterns
.
X393McntrlEyepattern
(
verbose
,
args
.
simulated
)
x393Adjust
=
x393_mcntrl_adjust
.
X393McntrlAdjust
(
verbose
,
args
.
simulated
,
args
.
localparams
)
X393Membridge
=
x393_mcntrl_membridge
.
X393McntrlMembridge
(
verbose
,
args
.
simulated
)
x393SensCmprs
=
x393_sens_cmprs
.
X393SensCmprs
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393Camsync
=
x393_camsync
.
X393Camsync
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393GPIO
=
x393_gpio
.
X393GPIO
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393CmprsAfi
=
x393_cmprs_afi
.
X393CmprsAfi
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393Cmprs
=
x393_cmprs
.
X393Cmprs
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393mem
=
x393_mem
.
X393Mem
(
verbose
,
args
.
simulated
)
#add dry run parameter
x393utils
=
x393_utils
.
X393Utils
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393tasks
=
x393_axi_control_status
.
X393AxiControlStatus
(
verbose
,
args
.
simulated
)
x393Pio
=
x393_pio_sequences
.
X393PIOSequences
(
verbose
,
args
.
simulated
)
x393Timing
=
x393_mcntrl_timing
.
X393McntrlTiming
(
verbose
,
args
.
simulated
)
x393Buffers
=
x393_mcntrl_buffers
.
X393McntrlBuffers
(
verbose
,
args
.
simulated
)
x393Tests
=
x393_mcntrl_tests
.
X393McntrlTests
(
verbose
,
args
.
simulated
)
x393Eyepatterns
=
x393_mcntrl_eyepatterns
.
X393McntrlEyepattern
(
verbose
,
args
.
simulated
)
x393Adjust
=
x393_mcntrl_adjust
.
X393McntrlAdjust
(
verbose
,
args
.
simulated
,
args
.
localparams
)
X393Membridge
=
x393_mcntrl_membridge
.
X393McntrlMembridge
(
verbose
,
args
.
simulated
)
x393SensCmprs
=
x393_sens_cmprs
.
X393SensCmprs
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393Camsync
=
x393_camsync
.
X393Camsync
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393GPIO
=
x393_gpio
.
X393GPIO
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393CmprsAfi
=
x393_cmprs_afi
.
X393CmprsAfi
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393Cmprs
=
x393_cmprs
.
X393Cmprs
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393FrameSequencer
=
x393_frame_sequencer
.
X393FrameSequencer
(
verbose
,
args
.
simulated
,
args
.
localparams
)
x393Sensor
=
x393_sensor
.
X393Sensor
(
verbose
,
args
.
simulated
,
args
.
localparams
)
'''
print ("----------------------")
print("x393_mem.__dict__="+str(x393_mem.__dict__))
...
...
@@ -372,6 +375,8 @@ USAGE
extractTasks
(
x393_gpio
.
X393GPIO
,
x393GPIO
)
extractTasks
(
x393_cmprs_afi
.
X393CmprsAfi
,
x393CmprsAfi
)
extractTasks
(
x393_cmprs
.
X393Cmprs
,
x393Cmprs
)
extractTasks
(
x393_frame_sequencer
.
X393FrameSequencer
,
x393FrameSequencer
)
extractTasks
(
x393_sensor
.
X393Sensor
,
x393Sensor
)
for
cmdLine
in
commands
:
print
(
'Running task: '
+
str
(
cmdLine
))
...
...
py393/x393_axi_control_status.py
View file @
d9f09d9d
...
...
@@ -318,85 +318,6 @@ class X393AxiControlStatus(object):
self
.
program_status
(
vrlg
.
MCNTRL_TEST01_ADDR
,
vrlg
.
MCNTRL_TEST01_CHN4_STATUS_CNTRL
,
mode
,
seq_num
)
#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR= 'h3e,
self
.
program_status
(
vrlg
.
MEMBRIDGE_ADDR
,
vrlg
.
MEMBRIDGE_STATUS_CNTRL
,
mode
,
seq_num
)
#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR= 'h3e,
def
program_status_sensor_i2c
(
self
,
num_sensor
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected sensor port i2c control
@param num_sensor - number of the sensor port (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
program_status
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
+
vrlg
.
SENSI2C_CTRL_RADDR
,
vrlg
.
SENSI2C_STATUS
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
def
program_status_sensor_io
(
self
,
num_sensor
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected sensor port io subsystem
@param num_sensor - number of the sensor port (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
program_status
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
+
vrlg
.
SENSIO_RADDR
,
vrlg
.
SENSIO_STATUS
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
def
program_status_compressor
(
self
,
cmprs_chn
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected compressor channel
@param cmprs_chn - number of the compressor channel (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
program_status
(
vrlg
.
CMPRS_GROUP_ADDR
+
cmprs_chn
*
vrlg
.
CMPRS_BASE_INC
,
vrlg
.
CMPRS_STATUS_CNTRL
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
'''
def program_status_gpio(self,
mode, # input [1:0] mode;
seq_num): # input [5:0] seq_num;
"""
Set status generation mode for GPIO port
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self.program_status (vrlg.GPIO_ADDR,
vrlg.GPIO_SET_STATUS,
mode,
seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
'''
def
enable_cmda
(
self
,
en
):
# input en;
"""
...
...
py393/x393_cmprs.py
View file @
d9f09d9d
...
...
@@ -57,6 +57,26 @@ class X393Cmprs(object):
except
:
pass
def
program_status_compressor
(
self
,
cmprs_chn
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected compressor channel
@param cmprs_chn - number of the compressor channel (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
x393_axi_tasks
.
program_status
(
vrlg
.
CMPRS_GROUP_ADDR
+
cmprs_chn
*
vrlg
.
CMPRS_BASE_INC
,
vrlg
.
CMPRS_STATUS_CNTRL
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
def
func_compressor_format
(
self
,
num_macro_cols_m1
,
num_macro_rows_m1
,
...
...
py393/x393_frame_sequencer.py
0 → 100644
View file @
d9f09d9d
from
__future__
import
division
from
__future__
import
print_function
'''
# Copyright (C) 2015, Elphel.inc.
# Class to control 10393 Frame sequencer that allows storing and applying
# register writes synchronized by the sensors frame sync
# 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
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@author: Andrey Filippov
@copyright: 2015 Elphel, Inc.
@license: GPLv3.0+
@contact: andrey@elphel.coml
@deffield updated: Updated
'''
__author__
=
"Andrey Filippov"
__copyright__
=
"Copyright 2015, Elphel, Inc."
__license__
=
"GPL"
__version__
=
"3.0+"
__maintainer__
=
"Andrey Filippov"
__email__
=
"andrey@elphel.com"
__status__
=
"Development"
#import sys
#import pickle
from
x393_mem
import
X393Mem
import
x393_axi_control_status
import
x393_utils
#import time
import
vrlg
class
X393FrameSequencer
(
object
):
DRY_MODE
=
True
# True
DEBUG_MODE
=
1
x393_mem
=
None
x393_axi_tasks
=
None
#x393X393AxiControlStatus
x393_utils
=
None
verbose
=
1
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
,
saveFileName
=
None
):
self
.
DEBUG_MODE
=
debug_mode
self
.
DRY_MODE
=
dry_mode
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
:
pass
def
ctrl_cmd_frame_sequencer
(
self
,
num_sensor
,
reset
=
False
,
start
=
False
,
stop
=
False
):
"""
Control frame sequence
@param num_sensor - sensor channel number
@param reset - reset sequencer (also stops)
@param start - start sequencer
@param stop - stop sequencer
"""
data
=
0
;
if
reset
:
data
|=
1
<<
vrlg
.
CMDFRAMESEQ_RST_BIT
if
start
:
data
|=
1
<<
(
vrlg
.
CMDFRAMESEQ_RUN_BIT
-
1
)
if
start
or
stop
:
data
|=
1
<<
vrlg
.
CMDFRAMESEQ_RUN_BIT
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
CMDFRAMESEQ_ADDR_BASE
+
num_sensor
*
vrlg
.
CMDFRAMESEQ_ADDR_INC
+
vrlg
.
CMDFRAMESEQ_CTRL
,
data
)
def
write_cmd_frame_sequencer
(
self
,
num_sensor
,
relative
,
frame_addr
,
addr
,
data
):
"""
Schedule/execute frame sequence command (register write)
@param num_sensor - sensor channel number
@param relative - False - use absolute address (0..15), True - use relative (to current frame) address - 0..14
writes to relative address 0 are considered ASAP and do not wait for the frame sync
@param frame_addr - 4-bit frame address (relative or absolute), relative must be < 15
@param addr; // command address (register to which command should be applied), 32 word (not byte) address, relative to maxi0 space
@param data; // command data to write
"""
frame_addr
&=
0xf
if
relative
and
(
frame_addr
==
0xf
):
raise
Exception
(
"task write_cmd_frame_sequencer(): relative address 0xf is invalid, it is reserved for module control"
)
reg_addr
=
vrlg
.
CMDFRAMESEQ_ADDR_BASE
+
num_sensor
*
vrlg
.
CMDFRAMESEQ_ADDR_INC
+
(
vrlg
.
CMDFRAMESEQ_ABS
,
vrlg
.
CMDFRAMESEQ_REL
)[
relative
]
+
frame_addr
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
addr
)
# two writes to the same location - first is the register address
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data
)
# second is data to write to that register
py393/x393_gpio.py
View file @
d9f09d9d
...
...
@@ -125,9 +125,9 @@ class X393GPIO(object):
data
=
0
for
i
,
e
in
enumerate
(
ext
):
if
not
e
is
None
:
if
(
e
==
0
)
or
(
e
.
upper
()
==
"0"
)
or
(
e
.
upper
()
==
"L"
):
if
(
e
is
False
)
or
(
e
==
0
)
or
(
e
.
upper
()
==
"0"
)
or
(
e
.
upper
()
==
"L"
):
data
|=
1
<<
(
2
*
i
)
elif
(
e
==
1
)
or
(
e
.
upper
()
==
"1"
)
or
(
e
.
upper
()
==
"H"
):
elif
(
e
is
True
)
or
(
e
==
1
)
or
(
e
.
upper
()
==
"1"
)
or
(
e
.
upper
()
==
"H"
):
data
|=
2
<<
(
2
*
i
)
elif
e
.
upper
()
==
"I"
:
data
|=
3
<<
(
2
*
i
)
...
...
py393/x393_mcntrl_adjust.py
View file @
d9f09d9d
...
...
@@ -3763,7 +3763,7 @@ class X393McntrlAdjust(object):
else
:
raise
Exception
(
"set_delays_with_reinit failed to read with safe delays for phase=
%
d after re-initializing device, wl_rslt=
%
s"
%
(
phase
,
str
(
wl_rslt
)))
return
cmda_odly_early
[
phase
]
# safe command/add
er
ss delay
return
cmda_odly_early
[
phase
]
# safe command/add
re
ss delay
def
cmd_phase_step
(
phase
):
def
measure_block
(
dly
,
...
...
py393/x393_mcntrl_membridge.py
View file @
d9f09d9d
...
...
@@ -182,7 +182,7 @@ class X393McntrlMembridge(object):
def
membridge_setup
(
self
,
len64
,
# input [28:0] len64; # number of 64-bit words to transfer
width64
,
# input [28:0] width64; # frame width in 64-bit words
start64
,
# input [28:0] start64; # relative start add
er
ss of the transfer (set to 0 when writing lo_addr64)
start64
,
# input [28:0] start64; # relative start add
re
ss of the transfer (set to 0 when writing lo_addr64)
lo_addr64
=
None
,
# input [28:0] lo_addr64; # low address of the system memory range, in 64-bit words
size64
=
None
,
# input [28:0] size64; # size of the system memory range in 64-bit words
cache
=
0x3
,
...
...
py393/x393_pio_sequences.py
View file @
d9f09d9d
...
...
@@ -129,7 +129,7 @@ class X393PIOSequences(object):
x393_mcontr_encode_cmd
'''
def
func_encode_cmd
(
self
,
# function [31:0]
addr
,
# input [14:0] addr; // 15-bit row/column add
er
ss
addr
,
# input [14:0] addr; // 15-bit row/column add
re
ss
bank
,
# input [2:0] bank; // bank (here OK to be any)
rcw
,
# input [2:0] rcw; // RAS/CAS/WE, positive logic
odt_en
,
# input odt_en; // enable ODT
...
...
@@ -145,7 +145,7 @@ class X393PIOSequences(object):
buf_rst
):
# input buf_rst; // connect to external buffer (but only if not paused)
"""
Encode data into memory controller sequencer word
<addr> 15-bit row/column add
er
ss
<addr> 15-bit row/column add
re
ss
<bank> 3-bit bank address
<rcw> 3-bit combined {RAS,CAS,WE}, positive logic
<odt_en> enable ODT
...
...
@@ -161,7 +161,7 @@ class X393PIOSequences(object):
<buf_rst> reset external buffer page address to 0, increment page number
"""
return
(
((
addr
&
0x7fff
)
<<
17
)
|
# addr[14:0], // 15-bit row/column add
er
ss
((
addr
&
0x7fff
)
<<
17
)
|
# addr[14:0], // 15-bit row/column add
re
ss
((
bank
&
0x7
)
<<
14
)
|
# bank [2:0], // bank
((
rcw
&
0x7
)
<<
11
)
|
# rcw[2:0], // RAS/CAS/WE
((
0
,
1
)[
odt_en
]
<<
10
)
|
# odt_en, // enable ODT
...
...
@@ -829,7 +829,7 @@ class X393PIOSequences(object):
reset_dll
,
# input reset_dll;
verbose
=
0
):
"""
Setup sequence (at paramter-defined add
er
ss) to write MR0, MR1, MR2 and MR3 mode registers of DDR3 memory
Setup sequence (at paramter-defined add
re
ss) to write MR0, MR1, MR2 and MR3 mode registers of DDR3 memory
<reset_dll> reset memory DLL when running this sequence
<verbose> print data being written (default: False)
"""
...
...
py393/x393_sensor.py
0 → 100644
View file @
d9f09d9d
from
__future__
import
division
from
__future__
import
print_function
'''
# Copyright (C) 2015, Elphel.inc.
# 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
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@author: Andrey Filippov
@copyright: 2015 Elphel, Inc.
@license: GPLv3.0+
@contact: andrey@elphel.coml
@deffield updated: Updated
'''
__author__
=
"Andrey Filippov"
__copyright__
=
"Copyright 2015, Elphel, Inc."
__license__
=
"GPL"
__version__
=
"3.0+"
__maintainer__
=
"Andrey Filippov"
__email__
=
"andrey@elphel.com"
__status__
=
"Development"
#import sys
#import pickle
from
x393_mem
import
X393Mem
import
x393_axi_control_status
import
x393_utils
#import time
import
vrlg
class
X393Sensor
(
object
):
DRY_MODE
=
True
# True
DEBUG_MODE
=
1
x393_mem
=
None
x393_axi_tasks
=
None
#x393X393AxiControlStatus
x393_utils
=
None
verbose
=
1
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
,
saveFileName
=
None
):
self
.
DEBUG_MODE
=
debug_mode
self
.
DRY_MODE
=
dry_mode
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
:
pass
def
program_status_sensor_i2c
(
self
,
num_sensor
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected sensor port i2c control
@param num_sensor - number of the sensor port (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
program_status
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
+
vrlg
.
SENSI2C_CTRL_RADDR
,
vrlg
.
SENSI2C_STATUS
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
def
program_status_sensor_io
(
self
,
num_sensor
,
mode
,
# input [1:0] mode;
seq_num
):
# input [5:0] seq_num;
"""
Set status generation mode for selected sensor port io subsystem
@param num_sensor - number of the sensor port (0..3)
@param mode - status generation mode:
0: disable status generation,
1: single status request,
2: auto status, keep specified seq number,
4: auto, inc sequence number
@param seq_number - 6-bit sequence number of the status message to be sent
"""
self
.
x393_axi_tasks
.
program_status
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
+
vrlg
.
SENSIO_RADDR
,
vrlg
.
SENSIO_STATUS
,
mode
,
seq_num
)
# //MCONTR_PHY_STATUS_REG_ADDR= 'h0,
# Functions used by sensor-related tasks
def
func_sensor_mode
(
self
,
hist_en
,
hist_nrst
,
chn_en
,
bits16
):
"""
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 bits16) - True - 16 bpp mode, false - 8 bpp mode (bypass gamma). Gamma-processed data
is still used for histograms
@return: sensor mode control word
"""
rslt
=
0
;
rslt
|=
(
hist_en
&
0xf
)
<<
vrlg
.
SENSOR_HIST_EN_BITS
rslt
|=
(
hist_nrst
&
0xf
)
<<
vrlg
.
SENSOR_HIST_NRST_BITS
rslt
|=
((
0
,
1
)[
chn_en
])
<<
vrlg
.
SENSOR_CHN_EN_BIT
rslt
|=
((
0
,
1
)[
bits16
])
<<
vrlg
.
SENSOR_16BIT_BIT
return
rslt
def
func_sensor_i2c_command
(
self
,
rst_cmd
=
False
,
run_cmd
=
None
,
num_bytes
=
None
,
dly
=
None
,
scl_ctl
=
None
,
sda_ctl
=
None
):
"""
@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 num_bytes - set number of i2c bytes after slave address (0..3), None - no change
@param dly - set duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA??? obsolete)
@param scl_ctl - directly control SCL line: None - NOP, 'Z' - high Z, 0/False/'L' - low level,
1/True/'H' - high level
@param sda_ctl - directly control SDA line: None - NOP, 'Z' - high Z, 0/False/'L' - low level,
1/True/'H' - high level
@return: i2c control word
"""
rslt
=
0
rslt
|=
(
0
,
1
)[
rst_cmd
]
<<
vrlg
.
SENSI2C_CMD_RESET
if
not
run_cmd
is
None
:
rslt
|=
1
<<
vrlg
.
SENSI2C_CMD_RUN
rslt
|=
(
0
,
1
)[
run_cmd
]
<<
(
vrlg
.
SENSI2C_CMD_RUN
-
vrlg
.
SENSI2C_CMD_RUN_PBITS
)
if
not
num_bytes
is
None
:
num_bytes
&=
(
1
<<
vrlg
.
SENSI2C_CMD_BYTES_PBITS
)
-
1
rslt
|=
1
<<
vrlg
.
SENSI2C_CMD_BYTES
rslt
|=
num_bytes
<<
(
vrlg
.
SENSI2C_CMD_BYTES
-
vrlg
.
SENSI2C_CMD_BYTES_PBITS
)
if
not
dly
is
None
:
dly
&=
(
1
<<
vrlg
.
SENSI2C_CMD_BYTES_PBITS
)
-
1
rslt
|=
1
<<
vrlg
.
SENSI2C_CMD_BYTES
rslt
|=
dly
<<
(
vrlg
.
SENSI2C_CMD_BYTES
-
vrlg
.
SENSI2C_CMD_BYTES_PBITS
)
scl
=
0
if
not
scl_ctl
is
None
:
if
(
scl_ctl
is
False
)
or
(
scl_ctl
==
0
)
or
(
scl_ctl
==
"0"
)
or
(
scl_ctl
.
upper
()
==
"L"
):
scl
=
1
elif
(
scl_ctl
is
True
)
or
(
scl_ctl
==
1
)
or
(
scl_ctl
==
"1"
)
or
(
scl_ctl
.
upper
()
==
"H"
):
scl
=
2
elif
scl_ctl
.
upper
()
==
"Z"
:
scl
=
3
rslt
|=
scl
<<
vrlg
.
SENSI2C_CMD_SCL
sda
=
0
if
not
sda_ctl
is
None
:
if
(
sda_ctl
is
False
)
or
(
sda_ctl
==
0
)
or
(
sda_ctl
==
"0"
)
or
(
sda_ctl
.
upper
()
==
"L"
):
sda
=
1
elif
(
sda_ctl
is
True
)
or
(
sda_ctl
==
1
)
or
(
sda_ctl
==
"1"
)
or
(
sda_ctl
.
upper
()
==
"H"
):
sda
=
2
elif
sda_ctl
.
upper
()
==
"Z"
:
sda
=
3
rslt
|=
sda
<<
vrlg
.
SENSI2C_CMD_SDA
return
rslt
def
func_sensor_io_ctl
(
self
,
mrst
=
None
,
arst
=
None
,
aro
=
None
,
mmcm_rst
=
None
,
clk_sel
=
None
,
set_delays
=
False
,
quadrants
=
None
):
"""
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 quadrants - 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] (6'h01), None - no change
@return sensor i/o control word
"""
rslt
=
0
if
not
mrst
is
None
:
rslt
|=
(
2
,
3
)[
mrst
]
<<
vrlg
.
SENS_CTRL_MRST
if
not
arst
is
None
:
rslt
|=
(
2
,
3
)[
arst
]
<<
vrlg
.
SENS_CTRL_ARST
if
not
aro
is
None
:
rslt
|=
(
2
,
3
)[
aro
]
<<
vrlg
.
SENS_CTRL_ARO
if
not
mmcm_rst
is
None
:
rslt
|=
(
2
,
3
)[
mmcm_rst
]
<<
vrlg
.
SENS_CTRL_RST_MMCM
if
not
clk_sel
is
None
:
rslt
|=
(
2
,
3
)[
clk_sel
]
<<
vrlg
.
SENS_CTRL_EXT_CLK
rslt
|=
(
0
,
1
)[
set_delays
]
<<
vrlg
.
SENS_CTRL_LD_DLY
if
not
quadrants
is
None
:
rslt
|=
1
<<
vrlg
.
SENS_CTRL_QUADRANTS_EN
rslt
|=
(
quadrants
&
((
1
<<
vrlg
.
SENS_CTRL_QUADRANTS_WIDTH
)
-
1
))
<<
vrlg
.
SENS_CTRL_QUADRANTS
return
rslt
def
func_sensor_jtag_ctl
(
self
,
pgmen
=
None
,
# <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control
prog
=
None
,
# <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control)
tck
=
None
,
# <2: keep TCK, 2 - set TCK low, 3 - set TCK high
tms
=
None
,
# <2: keep TMS, 2 - set TMS low, 3 - set TMS high
tdi
=
None
):
# <2: keep TDI, 2 - set TDI low, 3 - set TDI high
"""
JTAG interface for programming external sensor multiplexer using shared signal lines on the sensor ports
@param pgmen - False PGMEN low (inactive), True - high (active) enable JTAG control, None - keep previous value
@param prog - False prog low (active), True - high (inactive) ("program" pin control), None - keep previous value
@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
"""
rslt
=
0
if
not
pgmen
is
None
:
rslt
|=
(
2
,
3
)[
pgmen
]
<<
vrlg
.
SENS_JTAG_PGMEN
if
not
prog
is
None
:
rslt
|=
(
2
,
3
)[
prog
]
<<
vrlg
.
SENS_JTAG_PROG
if
not
tck
is
None
:
rslt
|=
(
2
,
3
)[
tck
]
<<
vrlg
.
SENS_JTAG_TCK
if
not
tms
is
None
:
rslt
|=
(
2
,
3
)[
tms
]
<<
vrlg
.
SENS_JTAG_TMS
if
not
tdi
is
None
:
rslt
|=
(
2
,
3
)[
tdi
]
<<
vrlg
.
SENS_JTAG_TDI
return
rslt
def
func_sensor_gamma_ctl
(
self
,
bayer
=
0
,
table_page
=
0
,
en_input
=
True
,
repet_mode
=
True
,
# Normal mode, single trigger - just for debugging TODO: re-assign?
trig
=
False
):
"""
@param bayer - Bayer shift (0..3)
@param table_page - Gamma table page
@param en_input - Enable input
@param repet_mode - Repetitive (normal) mode. Set False for debugging, then use trig for single frame trigger
@param trig - single trigger (when repet_mode is False), debug feature
@return combined control word
"""
rslt
=
0
rslt
|=
(
bayer
&
3
)
<<
vrlg
.
SENS_GAMMA_MODE_BAYER
rslt
|=
(
0
,
1
)[
table_page
]
<<
vrlg
.
SENS_GAMMA_MODE_PAGE
rslt
|=
(
0
,
1
)[
en_input
]
<<
vrlg
.
SENS_GAMMA_MODE_EN
rslt
|=
(
0
,
1
)[
repet_mode
]
<<
vrlg
.
SENS_GAMMA_MODE_REPET
rslt
|=
(
0
,
1
)[
trig
]
<<
vrlg
.
SENS_GAMMA_MODE_TRIG
return
rslt
def
func_status_addr_sensor_i2c
(
self
,
num_sensor
):
"""
@param num_sensor - sensor port number (0..3)
@return status register address for i2c for selected sensor port
"""
return
(
vrlg
.
SENSI2C_STATUS_REG_BASE
+
num_sensor
*
vrlg
.
SENSI2C_STATUS_REG_INC
+
vrlg
.
SENSI2C_STATUS_REG_REL
);
def
func_status_addr_sensor_io
(
self
,
num_sensor
):
"""
@param num_sensor - sensor port number (0..3)
@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
,
hist_nrst
,
chn_en
,
bits16
):
"""
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 bits16) - True - 16 bpp mode, false - 8 bpp mode (bypass gamma). Gamma-processed data
is still used for histograms
"""
self
.
x393_axi_tasks
.
write_contol_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
,
num_bytes
=
None
,
dly
=
None
,
scl_ctl
=
None
,
sda_ctl
=
None
):
"""
@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 num_bytes - set number of i2c bytes after slave address (0..3), None - no change
@param dly - set duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA??? obsolete)
@param scl_ctl - directly control SCL line: None - NOP, 'Z' - high Z, 0/False/'L' - low level,
1/True/'H' - high level
@param sda_ctl - directly control SDA line: None - NOP, 'Z' - high Z, 0/False/'L' - low level,
1/True/'H' - high level
@return: i2c control word
"""
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
+
vrlg
.
SENSI2C_CTRL_RADDR
,
self
.
func_sensor_i2c_command
(
rst_cmd
=
rst_cmd
,
run_cmd
=
run_cmd
,
num_bytes
=
num_bytes
,
dly
=
dly
,
scl_ctl
=
scl_ctl
,
sda_ctl
=
sda_ctl
))
def
write_sensor_i2c
(
self
,
num_sensor
,
rel_addr
,
addr
,
data
):
"""
Write i2c command to the i2c command sequencer
@param num_sensor - sensor port number (0..3)
@param rel_addr - True - relative frame address, False - absolute frame address
@param addr - frame address (0..15)
@param data - Combine slave address/register address/ register data for the i2c command
"""
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
reg_addr
+=
((
vrlg
.
SENSI2C_ABS_RADDR
,
vrlg
.
SENSI2C_REL_RADDR
)[
rel_addr
]
)
reg_addr
+=
(
addr
&
~
vrlg
.
SENSI2C_ADDR_MASK
);
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data
)
def
set_sensor_io_ctl
(
self
,
num_sensor
,
mrst
=
None
,
arst
=
None
,
aro
=
None
,
mmcm_rst
=
None
,
clk_sel
=
None
,
set_delays
=
False
,
quadrants
=
None
):
"""
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 quadrants - 90-degree shifts for data [1:0], hact [3:2] and vact [5:4] (6'h01), None - no change
"""
data
=
self
.
func_sensor_io_ctl
(
mrst
=
mrst
,
arst
=
arst
,
aro
=
aro
,
mmcm_rst
=
mmcm_rst
,
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_contol_register
(
reg_addr
,
data
)
def
set_sensor_io_dly
(
self
,
num_sensor
,
mmcm_phase
,
iclk_dly
,
vact_dly
,
hact_dly
,
pxd_dly
):
"""
Set sensor port input delays and mmcm phase
@param num_sensor - sensor port number (0..3)
@param mmcm_phase - MMCM clock phase
@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)
"""
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
))
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENSIO_RADDR
+
vrlg
.
SENSIO_DELAYS
;
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
0
,
dlys
[
0
])
# {pxd3, pxd2, pxd1, pxd0}
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
1
,
dlys
[
1
])
# {pxd7, pxd6, pxd5, pxd4}
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
2
,
dlys
[
2
])
# {pxd11, pxd10, pxd9, pxd8}
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
3
,
dlys
[
3
])
# {mmcm_phase, bpf, vact, hact}
self
.
set_sensor_io_ctl
(
num_sensor
=
num_sensor
,
set_delays
=
True
)
def
set_sensor_io_jtag
(
self
,
num_sensor
,
pgmen
=
None
,
# <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control
prog
=
None
,
# <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control)
tck
=
None
,
# <2: keep TCK, 2 - set TCK low, 3 - set TCK high
tms
=
None
,
# <2: keep TMS, 2 - set TMS low, 3 - set TMS high
tdi
=
None
):
# <2: keep TDI, 2 - set TDI low, 3 - set TDI high
"""
JTAG interface for programming external sensor multiplexer using shared signal lines on the sensor ports
@param num_sensor - sensor port number (0..3)
@param pgmen - False PGMEN low (inactive), True - high (active) enable JTAG control, None - keep previous value
@param prog - False prog low (active), True - high (inactive) ("program" pin control), None - keep previous value
@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
"""
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENSIO_RADDR
+
vrlg
.
SENSIO_JTAG
;
data
=
self
.
func_sensor_jtag_ctl
(
pgmen
=
pgmen
,
prog
=
prog
,
tck
=
tck
,
tms
=
tms
,
tdi
=
tdi
)
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data
)
def
set_sensor_io_width
(
self
,
num_sensor
,
width
):
# 0 - use HACT, >0 - generate HACT from start to specified width
"""
Set sensor frame width
@param num_sensor - sensor port number (0..3)
@param width - sensor 16-bit frame width (0 - use sensor HACT signal)
"""
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENSIO_RADDR
+
vrlg
.
SENSIO_WIDTH
;
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
width
)
def
set_sensor_lens_flat_heights
(
self
,
num_sensor
,
height0_m1
=
None
,
height1_m1
=
None
,
height2_m1
=
None
):
"""
Set division of the composite frame into sub-frames for the vignetting correction module
@param num_sensor - sensor port number (0..3)
@param height0_m1 - height of the first sub-frame minus 1
@param height1_m1 - height of the second sub-frame minus 1
@param height2_m1 - height of the third sub-frame minus 1
(No need for the 4-th, as it will just go until end of the composite frame)
"""
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_LENS_RADDR
;
if
not
height0_m1
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
0
,
height0_m1
)
if
not
height1_m1
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
1
,
height1_m1
)
if
not
height2_m1
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
2
,
height2_m1
)
def
set_sensor_lens_flat_parameters
(
self
,
num_sensor
,
num_sub_sensor
,
# add mode "DIRECT", "ASAP", "RELATIVE", "ABSOLUTE" and frame number
AX
=
None
,
AY
=
None
,
BX
=
None
,
BY
=
None
,
C
=
None
,
scales0
=
None
,
scales1
=
None
,
scales2
=
None
,
scales3
=
None
,
fatzero_in
=
None
,
fatzero_out
=
None
,
post_scale
=
None
):
"""
Program vignetting correction and per-color scale
@param num_sensor - sensor port number (0..3)
@param num_sub_sensor - sub-sensor attached to the same port through multiplexer (0..3)
TODO: add mode "DIRECT", "ASAP", "RELATIVE", "ABSOLUTE" and frame number for sequencer
All the next parameters can be None - will not be set
@param AX (19 bits)
@param AY (19 bits)
@param BX (21 bits)
@param BY (21 bits)
@param C (19 bits)
@param scales0 (17 bits) - color channel 0 scale
@param scales1 (17 bits) - color channel 1 scale
@param scales2 (17 bits) - color channel 2 scale
@param scales3 (17 bits) - color channel 3 scale
@param fatzero_in (16 bits)
@param fatzero_out (16 bits)
@param post_scale (4 bits) - shift of the result
"""
def
func_lens_data
(
self
,
num_sensor
,
addr
,
data
,
width
):
return
((
num_sensor
&
3
)
<<
24
)
|
((
addr
&
0xff
)
<<
16
)
|
(
data
&
((
1
<<
width
)
-
1
))
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_LENS_RADDR
+
vrlg
.
SENS_LENS_COEFF
if
not
AX
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_AX
,
AX
,
19
))
if
not
AY
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_AY
,
AY
,
19
))
if
not
BX
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_BX
,
BX
,
21
))
if
not
BY
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_BY
,
BY
,
21
))
if
not
C
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_C
,
C
,
19
))
if
not
scales0
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_SCALES
+
0
,
scales0
,
17
))
if
not
scales1
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_SCALES
+
2
,
scales1
,
17
))
if
not
scales2
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_SCALES
+
4
,
scales2
,
17
))
if
not
scales3
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_SCALES
+
6
,
scales3
,
17
))
if
not
fatzero_in
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_FAT0_IN
,
fatzero_in
,
16
))
if
not
fatzero_out
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_FAT0_OUT
,
fatzero_out
,
16
))
if
not
post_scale
is
None
:
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
func_lens_data
(
num_sub_sensor
,
vrlg
.
SENS_LENS_POST_SCALE
,
post_scale
,
4
))
def
program_curves
(
self
,
num_sensor
,
sub_channel
,
curves_data
,
page
=
0
):
"""
Program gamma tables for specified sensor port and subchannel
@param num_sensor - sensor port number (0..3)
@param num_sub_sensor - sub-sensor attached to the same port through multiplexer (0..3)
@param curves_data - either 1028-element list (257 per color component) or a file path
with the same data, same as for Verilog $readmemh
@param page - gammma table page number (only used if SENS_GAMMA_BUFFER > 0
"""
def
set_sensor_gamma_table_addr
(
num_sensor
,
sub_channel
,
color
,
page
=
0
):
# only used if SENS_GAMMA_BUFFER != 0
data
=
(
1
<<
20
)
|
((
color
&
3
)
<<
8
)
if
(
vrlg
.
SENS_GAMMA_BUFFER
):
data
|=
(
sub_channel
&
3
)
<<
11
# [12:11]
data
|=
page
<<
10
else
:
data
|=
(
sub_channel
&
3
)
<<
10
# [11:10]
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_GAMMA_RADDR
+
vrlg
.
SENS_GAMMA_ADDR_DATA
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data
)
def
set_sensor_gamma_table_data
(
#; // need 256 for a single color data
num_sensor
,
data18
):
# ; // 18-bit table data
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_GAMMA_RADDR
+
vrlg
.
SENS_GAMMA_ADDR_DATA
;
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data18
&
((
1
<<
18
)
-
1
))
if
isinstance
(
curves_data
,
unicode
):
with
open
(
curves_data
)
as
f
:
tokens
=
f
.
read
()
.
split
()
curves_data
=
[]
for
w
in
tokens
:
curves_data
.
append
(
int
(
w
,
16
))
set_sensor_gamma_table_addr
(
num_sensor
=
num_sensor
,
sub_channel
=
sub_channel
,
color
=
0
,
page
=
page
)
for
n
in
range
(
4
):
for
i
in
range
(
256
):
base
=
curves_data
[
257
*
n
+
i
];
diff
=
curves_data
[
257
*
n
+
i
+
1
]
-
curves_data
[
257
*
n
+
i
];
diff1
=
curves_data
[
257
*
n
+
i
+
1
]
-
curves_data
[
257
*
n
+
i
]
+
8
;
# $display ("%x %x %x %x %x %x",n,i,curves_data[257*n+i], base, diff, diff1);
#1;
if
((
diff
>
63
)
or
(
diff
<
-
64
)):
data18
=
(
1
<<
17
)
|
(
base
&
0x3ff
)
|
(((
diff1
>>
4
)
&
0x7f
)
<<
10
)
# {1'b1,diff1[10:4],base[9:0]};
else
:
data18
=
(
base
&
0x3ff
)
|
((
diff
&
0x7f
)
<<
10
)
# {1'b0,diff [ 6:0],base[9:0]};
set_sensor_gamma_table_data
(
num_sensor
=
num_sensor
,
data18
=
data18
)
def
set_sensor_gamma_heights
(
self
,
num_sensor
,
height0_m1
,
height1_m1
,
height2_m1
):
"""
Set division of the composite frame into sub-frames for gamma correction (separate for each subframe
@param num_sensor - sensor port number (0..3)
@param height0_m1 - height of the first sub-frame minus 1
@param height1_m1 - height of the second sub-frame minus 1
@param height2_m1 - height of the third sub-frame minus 1
(No need for the 4-th, as it will just go until end of the composite frame)
"""
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_GAMMA_RADDR
+
vrlg
.
SENS_GAMMA_HEIGHT01
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
(
height0_m1
&
0xffff
)
|
((
height1_m1
&
0xffff
)
<<
16
));
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_GAMMA_RADDR
+
vrlg
.
SENS_GAMMA_HEIGHT2
;
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
height2_m1
&
0xffff
);
def
set_sensor_gamma_ctl
(
self
,
num_sensor
,
bayer
=
0
,
table_page
=
0
,
en_input
=
True
,
repet_mode
=
True
,
# Normal mode, single trigger - just for debugging TODO: re-assign?
trig
=
False
):
"""
Setup sensor gamma correction
@param num_sensor - sensor port number (0..3)
@param bayer - Bayer shift (0..3)
@param table_page - Gamma table page
@param en_input - Enable input
@param repet_mode - Repetitive (normal) mode. Set False for debugging, then use trig for single frame trigger
@param trig - single trigger (when repet_mode is False), debug feature
"""
data
=
self
.
func_sensor_gamma_ctl
(
bayer
=
bayer
,
table_page
=
table_page
,
en_input
=
en_input
,
repet_mode
=
repet_mode
,
trig
=
trig
)
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
vrlg
.
SENS_GAMMA_RADDR
+
vrlg
.
SENS_GAMMA_CTRL
;
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
,
data
);
def
set_sensor_histogram_window
(
self
,
num_sensor
,
subchannel
,
left
,
top
,
width_m1
,
height_m1
):
"""
Program histogram window
@param num_sensor - sensor port number (0..3)
@param num_sub_sensor - sub-sensor attached to the same port through multiplexer (0..3)
@param left - histogram window left margin
@param top - histogram window top margin
@param width_m1 - one less than window width. If 0 - use frame right margin (end of HACT)
@param height_m1 - one less than window height. If 0 - use frame bottom margin (end of VACT)
"""
raddr
=
(
vrlg
.
HISTOGRAM_RADDR0
,
vrlg
.
HISTOGRAM_RADDR1
,
vrlg
.
HISTOGRAM_RADDR2
,
vrlg
.
HISTOGRAM_RADDR3
)
reg_addr
=
(
vrlg
.
SENSOR_GROUP_ADDR
+
num_sensor
*
vrlg
.
SENSOR_BASE_INC
)
+
raddr
[
subchannel
&
3
]
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
vrlg
.
HISTOGRAM_LEFT_TOP
,
((
top
&
0xffff
)
<<
16
)
|
(
left
&
0xff
))
self
.
x393_axi_tasks
.
write_contol_register
(
reg_addr
+
vrlg
.
HISTOGRAM_WIDTH_HEIGHT
,
((
height_m1
&
0xffff
)
<<
16
)
|
(
width_m1
&
0xff
))
def
set_sensor_histogram_saxi
(
self
,
en
,
nrst
,
confirm_write
,
cache_mode
=
3
):
"""
Setup SAXI GP channel to transfer histograms (16 pages, up to 16 sensors) to the system memory
@param en - enable transfers
@param nrst - negated reset False - immediate reset, True - normal run;
@param confirm_write - wait for the write confirmed (over B channel) before switching channels
@param cache_mode AXI cache mode, default should be 4'h3
"""
data
=
0
;
data
|=
(
0
,
1
)[
en
]
<<
vrlg
.
HIST_SAXI_EN
data
|=
(
0
,
1
)[
nrst
]
<<
vrlg
.
HIST_SAXI_NRESET
data
|=
(
0
,
1
)[
confirm_write
]
<<
vrlg
.
HIST_CONFIRM_WRITE
data
|=
(
cache_mode
&
0xf
)
<<
vrlg
.
HIST_SAXI_AWCACHE
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
SENSOR_GROUP_ADDR
+
vrlg
.
HIST_SAXI_MODE_ADDR_REL
,
data
)
def
set_sensor_histogram_saxi_addr
(
self
,
num_sensor
,
subchannel
,
page
):
"""
Setup SAXI GP start address in 4KB pages (1 page - 1 subchannel histogram)
@param num_sensor - sensor port number (0..3)
@param num_sub_sensor - sub-sensor attached to the same port through multiplexer (0..3)
@param page - system memory page address (in 4KB units)
"""
channel
=
((
num_sensor
&
3
)
<<
2
)
+
(
subchannel
&
3
)
self
.
x393_axi_tasks
.
write_contol_register
(
vrlg
.
SENSOR_GROUP_ADDR
+
vrlg
.
HIST_SAXI_ADDR_REL
+
channel
,
page
)
timing/rtc393.v
View file @
d9f09d9d
...
...
@@ -25,7 +25,7 @@
module
rtc393
#(
parameter
RTC_ADDR
=
'h704
,
//..'h707
parameter
RTC_STATUS_REG_ADDR
=
'h31
,
// address where status can be read out (currently just sequence # and alternating bit)
parameter
RTC_SEC_USEC_ADDR
=
'h32
,
//'h33 address where seconds of the snapshot can be read (microseconds - next add
er
ss)
parameter
RTC_SEC_USEC_ADDR
=
'h32
,
//'h33 address where seconds of the snapshot can be read (microseconds - next add
re
ss)
parameter
RTC_MASK
=
'h7fc
,
parameter
RTC_MHZ
=
25
,
// RTC input clock in MHz (should be interger number)
...
...
timing/timing393.v
View file @
d9f09d9d
...
...
@@ -24,7 +24,7 @@ module timing393 #(
parameter
RTC_ADDR
=
'h704
,
// 'h707
parameter
CAMSYNC_ADDR
=
'h708
,
// 'h70f
parameter
RTC_STATUS_REG_ADDR
=
'h31
,
// (1 loc) address where status can be read out (currently just sequence # and alternating bit)
parameter
RTC_SEC_USEC_ADDR
=
'h32
,
// ..'h33 address where seconds of the snapshot can be read (microseconds - next add
er
ss)
parameter
RTC_SEC_USEC_ADDR
=
'h32
,
// ..'h33 address where seconds of the snapshot can be read (microseconds - next add
re
ss)
parameter
RTC_MASK
=
'h7fc
,
parameter
CAMSYNC_MASK
=
'h7f8
,
parameter
CAMSYNC_MODE
=
'h0
,
...
...
x393.v
View file @
d9f09d9d
...
...
@@ -285,7 +285,7 @@ module x393 #(
wire
status_compressor_start
;
//
// TODO: Add sequencer status (16+2) bits of current frame number. Ose 'h31 as the add
er
ss, 'h702 (701..703 were empty) to program
// TODO: Add sequencer status (16+2) bits of current frame number. Ose 'h31 as the add
re
ss, 'h702 (701..703 were empty) to program
wire
[
7
:
0
]
status_sequencer_ad
;
// Other status byte-wide address/data
wire
status_sequencer_rq
;
// Other status request
wire
status_sequencer_start
;
// S uppressThisWarning VEditor ****** Other status packet transfer start (currently with 0 latency from status_root_rq)
...
...
x393_testbench02.tf
View file @
d9f09d9d
...
...
@@ -2391,7 +2391,7 @@ task setup_sensor_channel;
set_sensor_histogram_saxi (
1'
b1
,
// input en;
1
'b1, // input nrst;
1'
b1
,
// input confirm_write; // wait for the write confirmed befo
er swict
hing channels
1'
b1
,
// input confirm_write; // wait for the write confirmed befo
re switc
hing channels
4
'h3); // input [3:0] cache_mode; // default should be 4'
h3
/*
...
...
@@ -2812,7 +2812,7 @@ task test_i2c_353;
1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop
2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of qua
r
ter i2c cycle (if 0, [3:0] control SCL+SDA)
2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
repeat (10) @ (posedge CLK); // wait for initialization to be done TODO: use status
...
...
@@ -2848,7 +2848,7 @@ task test_i2c_353;
endtask
//x393_
axi_control_status
.py
//x393_
sensor
.py
task program_status_sensor_i2c;
input [1:0] num_sensor;
input [1:0] mode;
...
...
@@ -2861,7 +2861,7 @@ task program_status_sensor_i2c;
end
endtask
//x393_
axi_control_status
.py
//x393_
sensor
.py
task program_status_sensor_io;
input [1:0] num_sensor;
input [1:0] mode;
...
...
@@ -2874,7 +2874,7 @@ task program_status_sensor_io;
end
endtask
//x393_
axi_control_statu
s.py
//x393_
cmpr
s.py
task program_status_compressor;
input [1:0] num_sensor;
input [1:0] mode;
...
...
@@ -2968,7 +2968,7 @@ task set_sensor_i2c_command;
input set_bytes; // [11] if 1, use bytes (below), 0 - nop
input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
input set_dly; // [8] if 1, use dly (0 - ignore)
input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA)
input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of qua
r
ter i2c cycle (if 0, [3:0] control SCL+SDA)
input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
...
...
@@ -3299,7 +3299,7 @@ endtask
task set_sensor_histogram_saxi;
input en;
input nrst;
input confirm_write; // wait for the write confirmed befo
er swict
hing channels
input confirm_write; // wait for the write confirmed befo
re switc
hing channels
input [3:0] cache_mode; // default should be 4'h3
reg [31:0] data;
begin
...
...
@@ -3373,7 +3373,7 @@ function [STATUS_DEPTH-1:0] func_status_addr_rtc_usec; // sec is in the next add
endfunction
*/
// camsync tasks
//x393_camsync.py
//
x393_camsync.py
task set_camsync_mode;
input en; // 1 - enable, 0 - reset module
input [1:0] en_snd; // <2 - NOP, 2 - disable, 3 - enable sending timestamp with sync pulse
...
...
@@ -3394,7 +3394,7 @@ task set_camsync_mode;
end
endtask
//x393_camsync.py
//
x393_camsync.py
task set_camsync_inout; // set specified input bit, keep other ones
input is_out; // 0 - input selection, 1 - output selection
input integer bit_number; // 0..9 - bit to use
...
...
@@ -3408,6 +3408,7 @@ task set_camsync_inout; // set specified input bit, keep other ones
end
endtask
// x393_camsync.py
task reset_camsync_inout; // disable all inputs
input is_out; // 0 - input selection, 1 - output selection
begin
...
...
@@ -3416,6 +3417,7 @@ task reset_camsync_inout; // disable all inputs
end
endtask
// x393_camsync.py
task set_camsync_period;
input [31:0] period; // 0 - input selection, 1 - output selection
begin
...
...
@@ -3423,6 +3425,7 @@ task set_camsync_period;
end
endtask
// x393_camsync.py
task set_camsync_delay;
input [1:0] sub_chn;
input [31:0] dly; // 0 - input selection, 1 - output selection
...
...
@@ -3433,6 +3436,7 @@ endtask
// command sequencer control
// Functions used by sensor-related tasks
// x393_frame_sequencer.py
task ctrl_cmd_frame_sequencer;
input [1:0] num_sensor; // sensor channel number
input reset; // reset sequencer (also stops)
...
...
@@ -3450,16 +3454,17 @@ task ctrl_cmd_frame_sequencer;
end
endtask
// x393_frame_sequencer.py
task write_cmd_frame_sequencer;
input [1:0] num_sensor; // sensor channel number
input relative; // 0 - absolute (address = 0..f), 1 - relative (address= 0..e)
input [3:0] frame_addr; // frame address (relative or
t
absolute)
input [3:0] frame_addr; // frame address (relative or absolute)
input [AXI_WR_ADDR_BITS-1:0] addr; // command address (register to which command should be applied)
input [31:0] data; // command data
reg [29:0] reg_addr;
begin
if (relative && (&frame_addr)) $display("task write_cmd_frame_sequencer(): relative add
er
ss 'hf is invalid, it is reserved for module control");
if (relative && (&frame_addr)) $display("task write_cmd_frame_sequencer(): relative add
re
ss 'hf is invalid, it is reserved for module control");
else begin
reg_addr = CMDFRAMESEQ_ADDR_BASE + num_sensor * CMDFRAMESEQ_ADDR_INC + (relative ? CMDFRAMESEQ_REL : CMDFRAMESEQ_ABS) + frame_addr;
write_contol_register(reg_addr, {{32-AXI_WR_ADDR_BITS{1'b0}}, addr});
...
...
@@ -3467,7 +3472,7 @@ task write_cmd_frame_sequencer;
end
end
endtask
// x393_sensor.py
function [SENSOR_MODE_WIDTH-1:0] func_sensor_mode;
input [3:0] hist_en; // [0..3] 1 - enable histogram modules, disable after processing the started frame
input [3:0] hist_nrst; // [4..7] 0 - immediately reset histogram module
...
...
@@ -3485,13 +3490,14 @@ function [SENSOR_MODE_WIDTH-1:0] func_sensor_mode;
endfunction
// x393_sensor.py
function [31 : 0] func_sensor_i2c_command;
input rst_cmd; // [14] reset all FIFO (takes 16 clock pulses), also - stops i2c until run command
input [SENSI2C_CMD_RUN_PBITS : 0] run_cmd; // [13:12]3 - run i2c, 2 - stop i2c (needed before software i2c), 1,0 - no change to run state
input set_bytes; // [11] if 1, use bytes (below), 0 - nop
input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
input set_dly; // [8] if 1, use dly (0 - ignore)
input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quater i2c cycle (if 0, [3:0] control SCL+SDA)
input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of qua
r
ter i2c cycle (if 0, [3:0] control SCL+SDA)
input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [17:16] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [19:18] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
...
...
@@ -3513,6 +3519,7 @@ endfunction
// x393_sensor.py
function [31 : 0] func_sensor_io_ctl;
input [1:0] mrst; // <2: keep MRST, 2 - MRST low (active), 3 - high (inactive)
input [1:0] arst; // <2: keep ARST, 2 - ARST low (active), 3 - high (inactive)
...
...
@@ -3533,11 +3540,12 @@ function [31 : 0] func_sensor_io_ctl;
tmp [SENS_CTRL_EXT_CLK +: 2] = clk_sel;
tmp [SENS_CTRL_LD_DLY] = set_delays;
tmp [SENS_CTRL_QUADRANTS_EN] = set_guadrants;
tmp [SENS_CTRL_
EXT_CLK +: SENS_CTRL_QUADRANTS_WIDTH] =
quadrants;
tmp [SENS_CTRL_
QUADRANTS +: SENS_CTRL_QUADRANTS_WIDTH] =
quadrants;
func_sensor_io_ctl = tmp;
end
endfunction
// x393_sensor.py
function [31 : 0] func_sensor_jtag_ctl;
input [1:0] pgmen; // <2: keep PGMEN, 2 - PGMEN low (inactive), 3 - high (active) enable JTAG control
input [1:0] prog; // <2: keep prog, 2 - prog low (active), 3 - high (inactive) ("program" pin control)
...
...
@@ -3548,9 +3556,8 @@ function [31 : 0] func_sensor_jtag_ctl;
reg [31 : 0] tmp;
begin
tmp = 0;
tmp [SENS_JTAG_TDI +: 2] = pgmen;
tmp [SENS_JTAG_TMS +: 2] = prog;
tmp [SENS_JTAG_PGMEN +: 2] = pgmen;
tmp [SENS_JTAG_PROG +: 2] = prog;
tmp [SENS_JTAG_TCK +: 2] = tck;
tmp [SENS_JTAG_TMS +: 2] = tms;
tmp [SENS_JTAG_TDI +: 2] = tdi;
...
...
@@ -3558,6 +3565,7 @@ function [31 : 0] func_sensor_jtag_ctl;
end
endfunction
// x393_sensor.py
function [31 : 0] func_sensor_gamma_ctl;
input [1:0] bayer;
input table_page;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment