Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
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
linux-elphel
Commits
cf4af6f5
Commit
cf4af6f5
authored
Aug 09, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More editing
parent
804b8db1
Changes
19
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
654 additions
and
407 deletions
+654
-407
circbuf-jtag.c
src/drivers/elphel/circbuf-jtag.c
+4
-4
circbuf.c
src/drivers/elphel/circbuf.c
+2
-2
detect_sensors.c
src/drivers/elphel/detect_sensors.c
+87
-20
detect_sensors.h
src/drivers/elphel/detect_sensors.h
+6
-0
framepars.c
src/drivers/elphel/framepars.c
+15
-4
framepars.h
src/drivers/elphel/framepars.h
+2
-0
histograms.c
src/drivers/elphel/histograms.c
+0
-2
imu_log393.c
src/drivers/elphel/imu_log393.c
+0
-2
mt9x001.c
src/drivers/elphel/mt9x001.c
+66
-30
multi10359.c
src/drivers/elphel/multi10359.c
+42
-31
multi10359.h
src/drivers/elphel/multi10359.h
+1
-0
pgm_functions.c
src/drivers/elphel/pgm_functions.c
+210
-136
pgm_functions.h
src/drivers/elphel/pgm_functions.h
+7
-0
sensor_common.c
src/drivers/elphel/sensor_common.c
+124
-45
sensor_common.h
src/drivers/elphel/sensor_common.h
+8
-1
sensor_i2c.c
src/drivers/elphel/sensor_i2c.c
+44
-0
sensor_i2c.h
src/drivers/elphel/sensor_i2c.h
+31
-130
x393_fpga_functions.c
src/drivers/elphel/x393_fpga_functions.c
+4
-0
c313a.h
src/include/elphel/c313a.h
+1
-0
No files found.
src/drivers/elphel/circbuf-jtag.c
View file @
cf4af6f5
...
...
@@ -76,7 +76,7 @@
/** Wait queue for the processes waiting for a new frame to appear in the circular buffer */
wait_queue_head_t
circbuf_wait_queue
;
struct
circbuf_priv_t
circbuf_priv
[
IMAGE_CHN_NUM
];
struct
circbuf_priv_t
circbuf_priv
[
SENSOR_PORTS
];
struct
circbuf_priv_t
*
circbuf_priv_ptr
=
circbuf_priv
;
static
struct
device
*
g_dev_ptr
;
...
...
@@ -109,7 +109,7 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
// set circular buffer size in bytes
set_globalParam
(
G_CIRCBUFSIZE
,
CCAM_DMA_SIZE
);
for
(
i
=
0
;
i
<
IMAGE_CHN_NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
SENSOR_PORTS
;
i
++
)
{
circbuf_priv
[
i
].
buf_ptr
=
ccam_dma_buf_ptr
+
BYTE2DW
(
CIRCBUF_START_OFFSET
+
i
*
CCAM_DMA_SIZE
);
circbuf_priv
[
i
].
phys_addr
=
dma_handle
+
CIRCBUF_START_OFFSET
+
i
*
CCAM_DMA_SIZE
;
}
...
...
@@ -572,10 +572,10 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
/* debug code follows*/
switch
(
buf
[
0
]
-
0x30
)
{
case
0
:
c
amera_interrupts
(
0
);
c
ompressor_interrupts
(
0
,
chn
);
break
;
case
1
:
c
amera_interrupts
(
1
);
c
ompressor_interrupts
(
1
,
chn
);
break
;
}
/* debug code end */
...
...
src/drivers/elphel/circbuf.c
View file @
cf4af6f5
...
...
@@ -753,10 +753,10 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
/* debug code follows*/
switch
(
buf
[
0
]
-
0x30
)
{
case
0
:
c
amera_interrupts
(
0
);
c
ompressor_interrupts
(
0
,
chn
);
break
;
case
1
:
c
amera_interrupts
(
1
);
c
ompressor_interrupts
(
1
,
chn
);
break
;
case
3
:
/* update image quality */
...
...
src/drivers/elphel/detect_sensors.c
View file @
cf4af6f5
...
...
@@ -60,25 +60,29 @@ struct sensor_name_t {
const
char
*
name
;
u32
code
;
int
type
;
///< +1 - applicable to sensors, +2 - applicable to multiplexers
sens_iface_t
iface
;
};
//typedef enum {NONE,PARALLEL12,HISPI} sens_iface_t; ///< Sensor port interface type
const
struct
sensor_name_t
sensor_names
[]
=
{
{.
name
=
"detect"
,
.
type
=
3
,
.
code
=
0
},
// to be automatically detected
{.
name
=
"none"
,
.
type
=
3
,
.
code
=
SENSOR_NONE
},
// no device attached
{.
name
=
"mux10359"
,
.
type
=
2
,
.
code
=
SENSOR_MUX_10359
},
// no device attached
{.
name
=
"zr32112"
,
.
type
=
1
,
.
code
=
SENSOR_ZR32112
},
// Zoran ZR32112
{.
name
=
"zr32212"
,
.
type
=
1
,
.
code
=
SENSOR_ZR32212
},
// Zoran ZR32212
{.
name
=
"kac1310"
,
.
type
=
1
,
.
code
=
SENSOR_KAC1310
},
// Kodak KAC1310
{.
name
=
"kac5000"
,
.
type
=
1
,
.
code
=
SENSOR_KAC5000
},
// Kodak KAC5000
{.
name
=
"mi1300"
,
.
type
=
1
,
.
code
=
SENSOR_MI1300
},
// Micron MI1300
{.
name
=
"mt9m001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9M001
},
// MT9M001
{.
name
=
"mt9d001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9D001
},
// MT9D001
{.
name
=
"mt9t001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9T001
},
// MT9T001
{.
name
=
"mt9p006"
,
.
type
=
1
,
.
code
=
SENSOR_MT9P006
},
// MT9P006
{.
name
=
"mt9f002"
,
.
type
=
1
,
.
code
=
SENSOR_MT9F002
},
// MT9F002
{.
name
=
"ibis51300"
,
.
type
=
1
,
.
code
=
SENSOR_IBIS51300
},
// FillFactory IBIS51300
{.
name
=
"kai11002"
,
.
type
=
1
,
.
code
=
SENSOR_KAI11000
},
// Kodak KAI11002
{.
name
=
NULL
,
.
type
=
0
,
.
code
=
0
}
// end of list
{.
name
=
"detect"
,
.
type
=
3
,
.
iface
=
NONE
,
.
code
=
0
},
// to be automatically detected
{.
name
=
"none"
,
.
type
=
3
,
.
iface
=
NONE
,
.
code
=
SENSOR_NONE
},
// no device attached
{.
name
=
"mux10359"
,
.
type
=
2
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MUX_10359
},
// no device attached
{.
name
=
"zr32112"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_ZR32112
},
// Zoran ZR32112
{.
name
=
"zr32212"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_ZR32212
},
// Zoran ZR32212
{.
name
=
"kac1310"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_KAC1310
},
// Kodak KAC1310
{.
name
=
"kac5000"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_KAC5000
},
// Kodak KAC5000
{.
name
=
"mi1300"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MI1300
},
// Micron MI1300
{.
name
=
"mt9m001"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MT9M001
},
// MT9M001
{.
name
=
"mt9d001"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MT9D001
},
// MT9D001
{.
name
=
"mt9t001"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MT9T001
},
// MT9T001
{.
name
=
"mt9p006"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_MT9P006
},
// MT9P006
{.
name
=
"mt9f002"
,
.
type
=
1
,
.
iface
=
HISPI4
,
.
code
=
SENSOR_MT9F002
},
// MT9F002
{.
name
=
"ibis51300"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_IBIS51300
},
// FillFactory IBIS51300
{.
name
=
"kai11002"
,
.
type
=
1
,
.
iface
=
PARALLEL12
,
.
code
=
SENSOR_KAI11000
},
// Kodak KAI11002
{.
name
=
NULL
,
.
type
=
0
,
.
iface
=
NONE
,
.
code
=
0
}
// end of list
};
static
sens_iface_t
port_iface
[
SENSOR_PORTS
];
//#define DETECT_SENSOR 1 ///< Include sensors, May be OR-ed when looking for sensor/multiplexer code/name
//#define DETECT_MUX 2 ///< Include multiplexers, May be OR-ed when looking for sensor/multiplexer code/name
...
...
@@ -111,6 +115,20 @@ const char * get_name_by_code(int code, ///< sensor code
return
NULL
;
}
/** Get sensor/multiplexer interface type by code */
sens_iface_t
get_iface_by_code
(
int
code
,
///< sensor code
int
type
)
///< valid type [DETECT_SENSOR]|[DETECT_MUX]
///< @return sensor name or NULL for invalid code
{
int
i
;
for
(
i
=
0
;
sensor_names
[
i
].
name
;
i
++
){
if
((
sensor_names
[
i
].
type
&
type
)
&&
(
sensor_names
[
i
].
code
==
code
)){
return
sensor_names
[
i
].
iface
;
}
}
return
NONE
;
}
/** Get sensor port multiplexer type */
int
get_detected_mux_code
(
int
port
)
///< Sensor port number (0..3)
...
...
@@ -120,12 +138,59 @@ int get_detected_mux_code(int port) ///< Sensor port number (0..3)
}
/** Get sensor type */
int
get_detected_sensor_code
(
int
port
,
///< Sensor port number (0..3)
int
sub_chn
)
///< Sensor subchannel (0..3)
int
sub_chn
)
///< Sensor subchannel (0..3)
, -1 - use first defined sub channel
///< @return sensor code (SENSOR_DETECT, SENSOR_NONE, or SENSOR_*)
{
return
sensorPortConfig
[
port
&
3
].
sensor
[
sub_chn
&
3
];
int
nchn
,
code
;
port
&=
3
;
if
(
sub_chn
>=
0
)
return
sensorPortConfig
[
port
].
sensor
[
sub_chn
&
3
];
// Negative sensor - find first defined
nchn
=
(
get_detected_mux_code
(
port
)
==
SENSOR_NONE
)
?
1
:
MAX_SENSORS
;
for
(
sub_chn
=
0
;
sub_chn
<
nchn
;
sub_chn
++
){
code
=
sensorPortConfig
[
port
].
sensor
[
sub_chn
];
if
((
code
!=
SENSOR_DETECT
)
&&
(
code
!=
SENSOR_NONE
))
return
code
;
}
return
SENSOR_NONE
;
}
/** Gert configured sensorport subchannels */
int
get_subchannels
(
int
port
)
///< Sensor port
///< @return bitmask of available channels
{
int
sub_chn
,
chn_mask
=
0
;
int
nchn
=
(
get_detected_mux_code
(
port
)
==
SENSOR_NONE
)
?
1
:
MAX_SENSORS
;
for
(
sub_chn
=
0
;
sub_chn
<
nchn
;
sub_chn
++
){
if
((
sensorPortConfig
[
port
].
sensor
[
sub_chn
]
!=
SENSOR_DETECT
)
&&
(
sensorPortConfig
[
port
].
sensor
[
sub_chn
]
!=
SENSOR_NONE
))
{
chn_mask
|=
1
<<
sub_chn
;
}
}
return
chn_mask
;
}
/** Update per-port interface type after changing sensor/multiplexer */
void
update_port_iface
(
int
port
)
///< Sensor port number (0..3)
{
sens_iface_t
iface
=
get_iface_by_code
(
get_detected_mux_code
(
port
),
DETECT_MUX
);
if
(
iface
!=
NONE
)
{
port_iface
[
port
]
=
iface
;
return
;
}
port_iface
[
port
]
=
get_iface_by_code
(
get_detected_sensor_code
(
port
,
-
1
),
DETECT_MUX
);
// '-1' - any subchannel
}
/** Get per-port interface type */
sens_iface_t
get_port_interface
(
int
port
)
///< Sensor port number (0..3)
///< @ return interface type (none, parallel12, hispi4
{
return
port_iface
[
port
];
}
/** Set sensor port multiplexer type */
int
set_detected_mux_code
(
int
port
,
///< Sensor port number (0..3)
int
mux_type
)
///< Sensor multiplexer type (SENSOR_DETECT, SENSOR_MUX_10359 or SENSOR_NONE)
...
...
@@ -138,6 +203,7 @@ int set_detected_mux_code(int port, ///< Sensor port number (0..3)
return
-
EINVAL
;
}
sensorPortConfig
[
port
&
3
].
mux
=
mux_type
;
update_port_iface
(
port
);
return
0
;
}
...
...
@@ -154,6 +220,7 @@ int set_detected_sensor_code(int port, ///< Sensor port number (0..3)
return
-
EINVAL
;
}
sensorPortConfig
[
port
&
3
].
sensor
[
sub_chn
]
=
sens_type
;
update_port_iface
(
port
);
return
0
;
}
...
...
@@ -182,7 +249,7 @@ static int get_channel_sub_from_name(struct device_attribute *attr) ///< Linux k
static
ssize_t
show_port_mux
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
i
;
const
char
*
name
=
get_name_by_code
(
sensorPortConfig
[
get_channel_from_name
(
attr
)].
mux
,
DETECT_MUX
);
const
char
*
name
=
get_name_by_code
(
get_detected_mux_code
(
get_channel_from_name
(
attr
))
,
DETECT_MUX
);
if
(
name
)
return
sprintf
(
buf
,
"%s
\n
"
,
name
);
// Should never get here
return
sprintf
(
buf
,
"0x%x
\n
"
,
sensorPortConfig
[
get_channel_from_name
(
attr
)].
mux
);
...
...
@@ -193,7 +260,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, ch
int
psch
=
get_channel_sub_from_name
(
attr
);
int
port
=
(
psch
>>
4
)
&
3
;
int
sub_chn
=
psch
&
3
;
const
char
*
name
=
get_name_by_code
(
sensorPortConfig
[
port
].
sensor
[
sub_chn
]
,
DETECT_SENSOR
);
const
char
*
name
=
get_name_by_code
(
get_detected_sensor_code
(
port
,
sub_chn
)
,
DETECT_SENSOR
);
if
(
name
)
return
sprintf
(
buf
,
"%s
\n
"
,
name
);
// Should never get here
return
sprintf
(
buf
,
"0x%x
\n
"
,
sensorPortConfig
[(
psch
>>
4
)
&
3
].
sensor
[
psch
&
3
]);
...
...
src/drivers/elphel/detect_sensors.h
View file @
cf4af6f5
...
...
@@ -20,9 +20,15 @@
#define DETECT_SENSOR 1 ///< Include sensors, May be OR-ed when looking for sensor/multiplexer code/name
#define DETECT_MUX 2 ///< Include multiplexers, May be OR-ed when looking for sensor/multiplexer code/name
typedef
enum
{
NONE
,
PARALLEL12
,
HISPI4
}
sens_iface_t
;
///< Sensor port interface type
int
get_code_by_name
(
const
char
*
name
,
int
type
);
const
char
*
get_name_by_code
(
int
code
,
int
type
);
sens_iface_t
get_iface_by_code
(
int
code
,
int
type
);
int
get_detected_mux_code
(
int
port
);
int
get_detected_sensor_code
(
int
port
,
int
sub_chn
);
int
get_subchannels
(
int
port
);
int
set_detected_mux_code
(
int
port
,
int
mux_type
);
int
set_detected_sensor_code
(
int
port
,
int
sub_chn
,
int
mux_type
);
sens_iface_t
get_port_interface
(
int
port
);
src/drivers/elphel/framepars.c
View file @
cf4af6f5
...
...
@@ -146,7 +146,7 @@ wait_queue_head_t aframepars_wait_queue[SENSOR_PORTS];// used to wait for
/* Remove after compilation OK */
struct
sensorproc_t
*
sensorproc
=
NULL
;
//void c
amera
_interrupts (int on) {}
//void c
ompressor
_interrupts (int on) {}
#if 0
#define wait_event_interruptible(wq, condition) \
({ \
...
...
@@ -353,6 +353,16 @@ inline unsigned long get_imageParamsPrev(int sensor_port, int n)
return
aframepars
[
sensor_port
][(
thisFrameNumber
(
sensor_port
)
-
1
)
&
PARS_FRAMES_MASK
].
pars
[
n
];
}
/** Reads past parameters (small subset of all) fro absolute frame number */
inline
unsigned
long
get_imageParamsPast
(
int
sensor_port
,
///< sensor port (0..3)
int
n
,
///< parameter index (should be 128..143)
int
frame
)
///< absolute frame number
{
return
apastpars
[
sensor_port
][
frame
&
PASTPARS_SAVE_ENTRIES_MASK
].
past_pars
[
n
-
PARS_SAVE_FROM
];
}
/**
* @brief writes read-only parameter to the current frame (does not propagate to next frames as setFramePar() does)
* In most cases you really need to use setFramePar() instead;
...
...
@@ -1181,11 +1191,12 @@ loff_t framepars_lseek(struct file * file, loff_t offset, int orig)
break
;
case
LSEEK_INTERRUPT_OFF
:
// disable camera interrupts
MDF2
(
printk
(
"LSEEK_INTERRUPT_OFF
\n
"
));
camera_interrupts
(
0
);
// compressor_interrupts(0,sensor_port);
sensor_interrupts
(
0
,
sensor_port
);
break
;
case
LSEEK_INTERRUPT_ON
:
// enable camera interrupts
MDF2
(
printk
(
"LSEEK_INTERRUPT_ON
\n
"
));
camera_interrupts
(
1
);
//
MDF2(printk("LSEEK_INTERRUPT_ON\n"));
sensor_interrupts
(
1
,
sensor_port
);
break
;
}
}
...
...
src/drivers/elphel/framepars.h
View file @
cf4af6f5
...
...
@@ -21,6 +21,8 @@ void resetFrameNumber (int sensor_port); /// reset this frame number (called fr
unsigned
long
get_imageParamsThis
(
int
sensor_port
,
int
n
);
unsigned
long
get_imageParamsPrev
(
int
sensor_port
,
int
n
);
unsigned
long
get_imageParamsPast
(
int
sensor_port
,
int
n
,
int
frame
);
void
set_imageParamsThis
(
int
sensor_port
,
int
n
,
unsigned
long
d
);
unsigned
long
get_globalParam
(
int
sensor_port
,
int
n
);
...
...
src/drivers/elphel/histograms.c
View file @
cf4af6f5
...
...
@@ -113,8 +113,6 @@
//#include "fpga_io.h"//fpga_table_write_nice
#include "framepars.h" // for debug mask
#include <elphel/elphel393-mem.h>
#include "legacy_defines.h" // temporarily
//#include "cc3x3.h"
#include "x393.h"
#include "histograms.h"
...
...
src/drivers/elphel/imu_log393.c
View file @
cf4af6f5
...
...
@@ -55,8 +55,6 @@
#include "imu_log393.h"
#include "x393.h"
#include "cci2c.h"
//#include "legacy_defines.h" // temporarily
#if 0
#define D(x) x
...
...
src/drivers/elphel/mt9x001.c
View file @
cf4af6f5
This diff is collapsed.
Click to expand it.
src/drivers/elphel/multi10359.c
View file @
cf4af6f5
This diff is collapsed.
Click to expand it.
src/drivers/elphel/multi10359.h
View file @
cf4af6f5
...
...
@@ -24,6 +24,7 @@
*/
#define I2C359_CLK_NUMBER 4 ///< OK with NC393, clock is ANDed with 3
//multisensor.h
//#define I2C359_INC 2 //< slave address increment between sensors in 10359A board (broadcast, 1,2,3) (7 bits SA) moved to sensor_common
...
...
src/drivers/elphel/pgm_functions.c
View file @
cf4af6f5
This diff is collapsed.
Click to expand it.
src/drivers/elphel/pgm_functions.h
View file @
cf4af6f5
...
...
@@ -17,6 +17,13 @@
*******************************************************************************/
#include "sensor_i2c.h"
#define COLOR_MARGINS 2 // add this many pixels each side
#define X313_TIMESTAMPLEN 28 // pixels used for timestamp (in linescan mode added after the line)
#define X393_TILEHOR 16
#define X393_TILEVERT 16
#define X393_MAXWIDTH 65536 // 4096 // multiple of 128
#define X393_MAXHEIGHT 65536 // 16384 // multiple of 16 - unsafe - not enough room for black level subtraction
#define X393_MAXHEIGHT_SAFE 65536 // 4096 // multiple of 16 OK for black level subtraction TODO: disable black level if unsafe
int
init_pgm_proc
(
void
);
int
add_sensor_proc
(
int
index
,
int
(
*
sens_func
)(
int
sensor_port
,
struct
sensor_t
*
,
struct
framepars_t
*
,
struct
framepars_t
*
,
int
));
...
...
src/drivers/elphel/sensor_common.c
View file @
cf4af6f5
This diff is collapsed.
Click to expand it.
src/drivers/elphel/sensor_common.h
View file @
cf4af6f5
...
...
@@ -15,6 +15,11 @@ extern struct sensorproc_t * sensorproc;
#ifdef CONFIG_ETRAX_ELPHEL_MT9X001
#include "mt9x001.h"
#endif
#define SEQ_CMD_STOP 0 ///< Sequencer command stop
#define SEQ_CMD_RUN 1 ///< Sequencer command run
#define SEQ_CMD_RESET 2 ///< Sequencer command reset
//#include "multisensor.h"
//int camSeqGetJPEG_wp(void);
//int camSeqGetJPEG_rp(void);
...
...
@@ -36,7 +41,9 @@ extern unsigned long * ccam_dma_buf_ptr[SENSOR_PORTS];
//int init_FPGA(void); /// can be initialized only after FPGA is configured, not at module init (NOTE was static??)
///can be verified with if (!X313_IS_SDRAM_ON)
void
reset_compressor
(
unsigned
int
chn
);
void
camera_interrupts
(
int
on
);
void
compressor_interrupts
(
int
on
,
int
chn
);
void
sensor_interrupts
(
int
on
,
int
chn
);
int
sequencer_stop_run_reset
(
int
chn
,
int
cmd
);
struct
sensorproc_t
*
copy_sensorproc
(
int
sensor_port
,
struct
sensorproc_t
*
copy
);
///NOTE: If profiling is enabled (TASKLET_CTL_ENPROF is set in G_TASKLET_CTL) - save current time in 2 of the 32-bit locations that can be read as pastpars (i.e. from PHP)
...
...
src/drivers/elphel/sensor_i2c.c
View file @
cf4af6f5
...
...
@@ -76,6 +76,50 @@ static int sysfs_page[4]; ///< when positive - page locked for exclus
static
struct
device
*
sdev
=
NULL
;
///< store this device here
static
u32
i2c_read_data
[
4
];
///< last data read from i2c device
/** I2C sequencer stop/run/reset (also programs status if run)*/
int
i2c_stop_run_reset
(
int
chn
,
///< Sensor port
int
cmd
)
///< Command: I2C_CMD_STOP=0 - stop, I2C_CMD_RUN=1 - run, I2C_CMD_RESET=2 - reset
///< @return always 0
{
x393_i2c_ctltbl_t
i2c_ctl
=
{.
d32
=
0
};
x393_status_ctrl_t
status_ctrl
=
{.
d32
=
0
};
switch
(
cmd
){
case
I2C_CMD_STOP
:
i2c_ctl
.
cmd_run
=
2
;
break
;
case
I2C_CMD_RUN
:
i2c_ctl
.
cmd_run
=
3
;
status_ctrl
.
mode
=
3
;
// autoupdate, is anyway set to it when reading i2c
break
;
case
I2C_CMD_RESET
:
i2c_ctl
.
reset
=
1
;
}
if
(
i2c_ctl
.
d32
)
x393_sensi2c_ctrl
(
i2c_ctl
,
chn
);
if
(
cmd
==
I2C_CMD_RESET
)
udelay
(
1
);
if
(
status_ctrl
.
mode
)
set_x393_sensi2c_status_ctrl
(
status_ctrl
,
chn
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
i2c_stop_run_reset
);
/** I2C sequencer drive mode */
int
i2c_drive_mode
(
int
chn
,
///< Sensor port
int
sda_drive_high
,
///< Actively drive SDA=1 during second half of SCL=1
int
sda_release
)
///< Release SDA early if next bit is SDA=1
///< @return always 0
{
x393_i2c_ctltbl_t
i2c_ctl
=
{.
d32
=
0
};
i2c_ctl
.
sda_drive_high
=
sda_drive_high
;
i2c_ctl
.
sda_release
=
sda_release
;
i2c_ctl
.
drive_ctl
=
1
;
x393_sensi2c_ctrl
(
i2c_ctl
,
chn
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
i2c_drive_mode
);
/** Mark all i2c pages for each channel as free */
void
i2c_page_alloc_init
(
void
)
{
...
...
src/drivers/elphel/sensor_i2c.h
View file @
cf4af6f5
...
...
@@ -17,6 +17,14 @@
#ifndef SENSOR_I2C_H
#define SENSOR_I2C_H
#define I2C_CMD_STOP 0
#define I2C_CMD_RUN 1
#define I2C_CMD_RESET 2
#define SDA_DRIVE_HIGH 1
#define SDA_RELEASE 1
/** I2C device description to be used with i2c sequencer*/
typedef
struct
{
char
name
[
32
];
///< Device class name (up to 31 characters)
...
...
@@ -27,136 +35,29 @@ typedef struct{
int
scl_khz
;
///< maximal SCL frequency in KHz (currently limited by 200KHz slowest)
}
x393_i2c_device_t
;
/** Reserve i2c page (1 of 256) for a sensor port
* @param chn sensor port number (0..3) */
int
i2c_page_alloc
(
int
chn
);
/* Register specific page, can be used with legacy software to register page equal to slave address,
* and use 0xff for reading. Works with 1byhte addresses and 16-bit data */
int
i2c_page_register
(
int
chn
,
// Sensor port
int
page
);
// page to register (for legacy software, use 7-bit slave address
// @return 0 on success, -ENOMEM if page is already registered
/* Free i2c page */
void
i2c_page_free
(
int
chn
,
int
page
);
/* Find device list entry by device class name */
x393_i2c_device_t
*
xi2c_dev_get
(
const
char
*
name
);
// Device class name as string
/* Set i2c table entry to raw data (will just overwrite tbl_mode = 2)*/
void
set_xi2c_raw
(
int
chn
,
int
page
,
// index in lookup table
u32
data
);
// Bit delay - number of mclk periods in 1/4 of the SCL period
/* Set i2c table entry for write operation */
void
set_xi2c_wr
(
int
chn
,
// sensor port
int
page
,
// index in lookup table
int
sa7
,
// slave address (7 bit)
int
rah
,
// High byte of the i2c register address
int
num_bytes
,
// Number of bytes to write (1..10)
int
bit_delay
);
// Bit delay - number of mclk periods in 1/4 of the SCL period
/*
* Set i2c table entry for write operation using known devices
* Get device with xi2c_dev_get(), copy and modify, if needed to
* offset slave address or change number of bytes to write, SCL frequency
*/
void
set_xi2c_wrc
(
x393_i2c_device_t
*
dc
,
// device class
int
chn
,
// sensor port
int
page
,
// index in lookup table
int
rah
);
// High byte of the i2c register address
/*
* Set i2c table entry for read operation using known devices
* Get device with xi2c_dev_get(), copy and modify, if needed to
* offset slave address or change number of bytes to write, SCL frequency
*/
void
set_xi2c_rdc
(
x393_i2c_device_t
*
dc
,
// device class
int
chn
,
// sensor port
int
page
);
// index in lookup table
/* Set i2c table entry for read operation */
void
set_xi2c_rd
(
int
chn
,
int
page
,
// index in lookup table
int
two_byte_addr
,
// Number of address bytes (0 - one byte, 1 - two bytes)
int
num_bytes
,
// Number of bytes to read (1..8, 0 means 8)
int
bit_delay
);
// Bit delay - number of mclk periods in 1/4 of the SCL period
/* Write one or multiple DWORDs to i2c relative (modulo16) address. Use offs = 0 for immediate (ASAP) command */
/* Length of data is determined by the page data already preset */
int
write_xi2c_rel
(
int
chn
,
int
offs
,
// 4 bits
u32
*
data
);
int
i2c_stop_run_reset
(
int
chn
,
int
cmd
);
int
i2c_drive_mode
(
int
chn
,
int
sda_drive_high
,
int
sda_release
);
int
write_xi2c_abs
(
int
chn
,
int
offs
,
// 4 bits
u32
*
data
);
/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void
write_xi2c_reg16
(
int
chn
,
int
page
,
// page (8 bits)
int
addr
,
// low 8 bits
u32
data
);
// 16 or 8-bit data (LSB aligned)
/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void
write_xi2c_reg16_rel
(
int
chn
,
// sensor port
int
page
,
// index in the table (8 bits)
int
frame
,
// relative frame number modulo PARS_FRAMES
int
addr
,
// low byte of the register address (high is in the table), 8 bits
u32
data
);
///< 16 or 8-bit data (LSB aligned)
/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void
write_xi2c_reg16_abs
(
int
chn
,
// sensor port
int
page
,
// index in the table (8 bits)
int
frame
,
// absolute frame number modulo PARS_FRAMES
int
addr
,
// low byte of the register address (high is in the table), 8 bits
u32
data
);
//16 or 8-bit data (LSB aligned)
/* Compatibility with the legacy code: frame <0 - ASAP, >=0 - absolute
* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void
write_xi2c_reg16_abs_asap
(
int
chn
,
// sensor port
int
page
,
// index in the table (8 bits)
int
frame
,
// absolute frame number modulo PARS_FRAMES
int
addr
,
// low byte of the register address (high is in the table), 8 bits
u32
data
);
// 16 or 8-bit data (LSB aligned)
/* Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo)
* Use slave address from provided class structure. */
void
read_xi2c
(
x393_i2c_device_t
*
dc
,
// device class
int
chn
,
int
page
,
// page (8 bits)
int
addr
);
// 8/16 bit address
/* Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo)*/
void
read_xi2c_sa7
(
int
chn
,
int
page
,
// page (8 bits)
int
sa7
,
// 7-bit i2c slave address
int
addr
);
// 8/16 bit address
/* Read next byte from the channel i2c FIFO. Return byte or -1 if no data available */
/* Sensor channel status should be in auto update mode (3) */
int
read_xi2c_fifo
(
int
chn
);
/* Handling classes of i2c devices */
int
i2c_page_alloc
(
int
chn
);
int
i2c_page_register
(
int
chn
,
int
page
);
void
i2c_page_free
(
int
chn
,
int
page
);
x393_i2c_device_t
*
xi2c_dev_get
(
const
char
*
name
);
/* Single-command i2c write/read register using pre-defined device classes */
int
x393_xi2c_write_reg
(
const
char
*
cname
,
// device class name
int
chn
,
// sensor port number
int
sa7_offs
,
// slave address (7-bit) offset from the class defined slave address
int
reg_addr
,
// register address (width is defined by class)
int
data
);
// data to write (width is defined by class)
int
x393_xi2c_read_reg
(
const
char
*
cname
,
// device class name
int
chn
,
// sensor port number
int
sa7_offs
,
// slave address (7-bit) offset from the class defined slave address
int
reg_addr
,
// register address (width is defined by class)
int
*
datap
);
// pointer to a data receiver (read data width is defined by class)
int
legacy_read_i2c_reg
(
int
chn
,
// sensor port number
int
page
,
// i2c table page registerd for read operation
int
sa7
,
// slave address (7-bit) of the device
// Offset is non-zero when multiple devices of the same class are present.
int
reg_addr
,
// register address (width is defined by class)
int
len
,
// number of bytes to read.
int
*
datap
);
// pointer to a data receiver (read data width is defined by class)
// @return 0 on success, < 0 - error (ETIMEDOUT)
void
set_xi2c_raw
(
int
chn
,
int
page
,
u32
data
);
void
set_xi2c_wr
(
int
chn
,
int
page
,
int
sa7
,
int
rah
,
int
num_bytes
,
int
bit_delay
);
void
set_xi2c_wrc
(
x393_i2c_device_t
*
dc
,
int
chn
,
int
page
,
int
rah
);
void
set_xi2c_rdc
(
x393_i2c_device_t
*
dc
,
int
chn
,
int
page
);
void
set_xi2c_rd
(
int
chn
,
int
page
,
int
two_byte_addr
,
int
num_bytes
,
int
bit_delay
);
int
write_xi2c_rel
(
int
chn
,
int
offs
,
u32
*
data
);
int
write_xi2c_abs
(
int
chn
,
int
offs
,
u32
*
data
);
void
write_xi2c_reg16
(
int
chn
,
int
page
,
int
addr
,
u32
data
);
void
write_xi2c_reg16_rel
(
int
chn
,
int
page
,
int
frame
,
int
addr
,
u32
data
);
void
write_xi2c_reg16_abs
(
int
chn
,
int
page
,
int
frame
,
int
addr
,
u32
data
);
void
write_xi2c_reg16_abs_asap
(
int
chn
,
int
page
,
int
frame
,
int
addr
,
u32
data
);
void
read_xi2c
(
x393_i2c_device_t
*
dc
,
int
chn
,
int
page
,
int
addr
);
void
read_xi2c_sa7
(
int
chn
,
int
page
,
int
sa7
,
int
addr
);
int
read_xi2c_fifo
(
int
chn
);
x393_i2c_device_t
*
xi2c_dev_get
(
const
char
*
name
);
int
x393_xi2c_write_reg
(
const
char
*
cname
,
int
chn
,
int
sa7_offs
,
int
reg_addr
,
int
data
);
int
x393_xi2c_read_reg
(
const
char
*
cname
,
int
chn
,
int
sa7_offs
,
int
reg_addr
,
int
*
datap
);
int
legacy_read_i2c_reg
(
int
chn
,
int
page
,
int
sa7
,
int
reg_addr
,
int
len
,
int
*
datap
);
#endif
src/drivers/elphel/x393_fpga_functions.c
View file @
cf4af6f5
...
...
@@ -18,3 +18,7 @@
#include "x393_fpga_functions.h"
int
init_command_sequencer
(
int
sensor_port
)
{
return
0
;
}
src/include/elphel/c313a.h
View file @
cf4af6f5
...
...
@@ -387,6 +387,7 @@
#define P_HISTRQ 72 ///< per-frame enabling of histogram calculation - bit 0 - Y (G), bit 2 - C (R,G2,B)
#define P_TILES 73 ///< Number of 16x16 (20x20) tiles in a compressed frame // 393: Still needed?
#define P_SENSOR_PHASE 74 ///< packed, low 16 bit - signed fine phase, bits [18:17] - 90-degrees shift
///< NC393 parallel12: 6 LSBs mean quadrants: 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
#define P_TEMPERATURE_PERIOD 75 ///< period of temperature measurements, ms (normally - multiple seconds)
#define P_AUTOEXP_ON 76 ///< Autoexposure control (unsigned long on)
// relative histogram (autoexposure) window (changed from % to 1/0x10000)
...
...
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