Commit cf4af6f5 authored by Andrey Filippov's avatar Andrey Filippov

More editing

parent 804b8db1
......@@ -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:
camera_interrupts(0);
compressor_interrupts(0,chn);
break;
case 1:
camera_interrupts(1);
compressor_interrupts(1,chn);
break;
}
/* debug code end */
......
......@@ -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:
camera_interrupts(0);
compressor_interrupts(0,chn);
break;
case 1:
camera_interrupts(1);
compressor_interrupts(1,chn);
break;
case 3:
/* update image quality */
......
......@@ -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]);
......
......@@ -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);
......@@ -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 camera_interrupts (int on) {}
//void compressor_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;
}
}
......
......@@ -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);
......
......@@ -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"
......
......@@ -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
......
......@@ -350,8 +350,7 @@
#include "framepars.h" // parameters manipulation
#include "sensor_common.h"
#include "pgm_functions.h"
//#include "x3x3.h" // hardware definitions
#include "legacy_defines.h" // temporarily
#include "x393.h"
#include "sensor_i2c.h"
......@@ -647,16 +646,16 @@ static unsigned short mt9p001_multiregs[]=
};
int mt9x001_pgm_detectsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_initsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_window (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_window_safe (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_window_common(int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_limitfps (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_exposure (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_gains (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_triggermode (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_sensorregs (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
int mt9x001_pgm_detectsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_initsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_window (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_window_safe (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_window_common(int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_limitfps (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_exposure (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_gains (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_triggermode (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9x001_pgm_sensorregs (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
// @brief read 2 bytes from i2c
#ifdef NC353
#define I2C_READ_DATA16(x) ((i2c_read_data[(x)<<1]<<8)+i2c_read_data[((x)<<1)+1])
......@@ -691,23 +690,24 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
int sensor_subtype=0;
int i;
struct sensor_t * psensor; // current sensor
MDF4(printk(" frame8=%d\n",frame8));
x393_sensio_ctl_t sensio_ctl = {.d32=0};
MDF4(printk(" frame16=%d\n",frame16));
// MDD1(printk("sensor=0x%x\n", (int)sensor));
if (thispars->pars[P_SENSOR]!=0) { ///already initialized - called second time after common pgm_detectsensor(), first time is inside pgm_detectsensor()
MDF1(printk(" sensor 0x%x already detected, exiting\n",(int) thispars->pars[P_SENSOR]));
return sensor->sensorType;
}
// try MT9P001 first
psensor= &mt9p001;
#ifdef NC353
// set control lines
CCAM_NEGRST; ///set negative MRST polarity
CCAM_TRIG_INT;
CCAM_MRST_OFF;
CCAM_ARST_OFF;
udelay (100);
// try MT9P001 first
psensor= &mt9p001;
#ifdef NC353
local_irq_save(flags); // IRQ Off
i2c_stop_wait();
i2c_writeData(0, (psensor->i2c_addr) & 0xfe, &chipver_reg, 1, 0); // no stop before read (cxi2c.c)
......@@ -718,6 +718,22 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
sensor_subtype=MT9P_TYP; //1;
}
#else
// set control lines
sensio_ctl.mrst = 1;
sensio_ctl.mrst_set = 1;
sensio_ctl.arst = 1;
sensio_ctl.arst_set = 1;
sensio_ctl.aro = 1;
sensio_ctl.aro_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
sensio_ctl.d32=0;
// reset mmcm
sensio_ctl.mmcm_rst = 1;
sensio_ctl.mmcm_rst_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
sensio_ctl.mmcm_rst = 0;
x393_sensio_ctrl(sensio_ctl,sensor_port);
udelay(50); // is it needed?
X3X3_I2C_RCV2(sensor_port, psensor->i2c_addr, P_MT9X001_CHIPVER, &i2c_read_dataw);
if (((i2c_read_dataw ^ MT9P001_PARTID) & MT9X001_PARTIDMASK)==0) {
printk("Found MT9P001 2592x1944 sensor, chip ID=%x\n",i2c_read_dataw);
......@@ -727,7 +743,7 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
// printk("sensor id= 0x%x\r\n",i2c_read_data[0]);
// MDD1(printk("sensor=0x%x\n", (int)sensor));
if (sensor_subtype ==0) { // not a 5MPix chip
CCAM_ARST_ON;
// CCAM_ARST_ON; // Why was it here
psensor= &mt9m001; //address the same for all others
#ifdef NC353
local_irq_save(flags); // IRQ Off
......@@ -823,8 +839,12 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
for (i=0;i<8;i++) {
// MDF(printk("i=%d, m=0x%lx\n",i,GLOBALPARS(G_MULTI_REGSM+i)));
}
// CCAM_ARO_ON ; //set Does it need to be set here? Not earlier (as it is now set for NC393
MDF4(printk(" set ARO (TRIGGER) line HIGH\n"));
CCAM_ARO_ON ; //set
sensio_ctl.d32=0;
sensio_ctl.aro = 1;
sensio_ctl.aro_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
return sensor->sensorType;
//NOTE 353: hardware i2c is turned off (not needed in 393)
}
......@@ -844,9 +864,11 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
struct frameparspair_t pars_to_update[258+(MAX_SENSORS * P_MULTI_NUMREGS )]; // for all the sensor registers. Other P_* values will reuse the same ones
int first_sensor_i2c;
unsigned short * sensor_register_overwrites;
MDF4(printk(" frame8=%d\n",frame8));
x393_sensio_ctl_t sensio_ctl = {.d32=0};
MDF4(printk(" frame16=%d\n",frame16));
if (frame16 >= 0) return -1; // should be ASAP
// int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
// int fpga_addr=(frame16 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame16);
// unsigned char i2c_read_data[512]; // each two bytes - one short word, big endian
u32 i2c_read_data_dw[256];
int nupdate=0;
......@@ -854,6 +876,7 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
int regval, regnum, mreg, j;
printk("Resetting MT9X001 sensor\r\n");
// reset sensor by applying MRST (low):
#ifdef NC353
CCAM_MRST_ON;
udelay (100);
CCAM_MRST_OFF;
......@@ -863,7 +886,6 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
if (GLOBALPARS(sensor_port, G_SENS_AVAIL)) {
first_sensor_i2c+= I2C359_INC * ((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 1)?1:((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 2)?2:3));
}
#ifdef NC353
i2c_read_data[0]=0;
local_irq_save(flags); // IRQ Off (rather long - all 256 registers through i2c, but there is no hurry - sensor is off)
i2c_stop_wait();
......@@ -884,7 +906,23 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
}
}
#else
for (i=0; i<256; i++) { // rdead all registers, one at a time (slower than in 353)
// CCAM_MRST_ON;
sensio_ctl.mrst = 0;
sensio_ctl.mrst_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
udelay (100);
// CCAM_MRST_OFF;
sensio_ctl.mrst = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
sensio_ctl.d32=0;
// NC393: both sequencers started in pgm_detectsensor
udelay (100);
printk("Reading sensor registers to the shadows:\r\n");
first_sensor_i2c=sensor->i2c_addr;
if (GLOBALPARS(sensor_port, G_SENS_AVAIL)) {
first_sensor_i2c+= I2C359_INC * ((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 1)?1:((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 2)?2:3));
}
for (i=0; i<256; i++) { // read all registers, one at a time (slower than in 353)
X3X3_I2C_RCV2(sensor_port, first_sensor_i2c, i, &(i2c_read_data_dw[i]));
}
for (i=0; i<256; i++) { // possible to modify register range to save (that is why nupdate is separate from i)
......@@ -927,8 +965,6 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
X3X3_SEQ_RUN;
local_irq_restore(flags); // IRQ restore
#else
X3X3_SEQ_RUN;
i2c_run();
#endif
nupdate=0; // Second pass over the registers to set
//#define SET_SENSOR_MBPAR(p,f,s,r,v)
......@@ -1038,11 +1074,11 @@ int mt9x001_pgm_window_common (int sensor_port, ///< sensor port
// flip margins for mirrored images (except oversized, not to rely on sensor->clearWidth/sensor->clearHeight
if (!thispars->pars[P_OVERSIZE]) {
if(flipX) {
wl = sensor->clearWidth - ww - wl - X313_MARGINS * dh;
wl = sensor->clearWidth - ww - wl - (2 * COLOR_MARGINS) * dh;
if(wl < 0) wl = 0;
}
if(flipY) {
wt = sensor->clearHeight - wh - wt - X313_MARGINS * dv;
wt = sensor->clearHeight - wh - wt - (2 * COLOR_MARGINS) * dv;
if(wt < 0) wt = 0;
}
// apply clearTop/clearLeft
......@@ -1160,7 +1196,7 @@ int mt9x001_pgm_limitfps (int sensor_port, ///< sensor port numb
uint64_t ull_fp1000s;
#endif
int target_virt_width=(thispars->pars[P_VIRT_KEEP])?(thispars->pars[P_VIRT_WIDTH]):0;
MDF4(printk(" frame8=%d\n",frame8));
MDF4(printk(" frame16=%d\n",frame16));
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
switch(styp) {
case MT9P_TYP: //page 16
......@@ -1925,7 +1961,7 @@ int mt9x001_pgm_sensorregs (int sensor_port, ///< sensor port
///< @return 0 - OK, negative - error
{
MDF4(printk(" frame8=%d\n",frame8));
MDF4(printk(" frame16=%d\n",frame16));
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
// send all parameters marked as "needed to be processed" to the sensor, clear those flags
// mask out all non sensor pars
......
......@@ -114,17 +114,15 @@
#include "framepars.h" // parameters manipulation
#include "sensor_common.h"
#include "pgm_functions.h"
//#include "x3x3.h" // hardware definitions
#include "legacy_defines.h" // temporarily
#include "sensor_i2c.h"
#include "clock10359.h"
#include "x393.h"
/**
* \def D(x) optional debug output
*/
#define X313_MARGINS 4
#if ELPHEL_DEBUG
#define MDF(x) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;}
......@@ -384,7 +382,7 @@ inline int sensor_wl(int wl, ///< Specified window left margin
int i,d;
if (!oversize) {
if(flipX) {
wl = sensor->clearWidth - ww - wl - X313_MARGINS * dh;
wl = sensor->clearWidth - ww - wl - (2 * COLOR_MARGINS) * dh;
if(wl < 0) wl = 0;
}
// apply clearTop/clearLeft
......@@ -427,7 +425,7 @@ inline int sensor_wt(int wt, ///< Specified window top margin
{
if (!oversize) {
if(flipY) {
wt = sensor->clearHeight - wh - wt - X313_MARGINS * dv;
wt = sensor->clearHeight - wh - wt - (2 * COLOR_MARGINS) * dv;
if(wt < 0) wt = 0;
}
// apply clearTop/clearLeft
......@@ -500,7 +498,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
bh= thispars->pars[P_BIN_HOR];
bv= thispars->pars[P_BIN_VERT];
ww= thispars->pars[P_SENSOR_PIXH] * dh;
// SETFRAMEPARS_SET(P_SENSOR_PIXV, height+X313_MARGINS); // full height for the sensor (after decimation), including margins
// SETFRAMEPARS_SET(P_SENSOR_PIXV, height+(2 * COLOR_MARGINS)); // full height for the sensor (after decimation), including margins
wh= thispars->pars[P_SENSOR_PIXV] * dv; // number of scan lines read from the sensor multipled by decimation
d = 2 * bh * (ww / (2 * bh));
if (unlikely(d != ww)) { // correct window width if needed
......@@ -526,12 +524,12 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
sequence = (sequence<<2) | (i & 3);
}
// Now sequence may be opposite to that of the P_MULTI_SEQUENCE
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0] += X313_MARGINS*dv; // include margins into individual sensor WOI-sizes
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1] += X313_MARGINS*dv;
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] += X313_MARGINS*dv;
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0]/dv) & ~1)+ X313_MARGINS)*dv; // include margins into individual sensor WOI-sizes, make even number of output lines
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1]/dv) & ~1)+ X313_MARGINS)*dv;
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2]/dv) & ~1)+ X313_MARGINS)*dv;
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0] += (2 * COLOR_MARGINS)*dv; // include margins into individual sensor WOI-sizes
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1] += (2 * COLOR_MARGINS)*dv;
// wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] += (2 * COLOR_MARGINS)*dv;
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0]/dv) & ~1)+ (2 * COLOR_MARGINS))*dv; // include margins into individual sensor WOI-sizes, make even number of output lines
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1]/dv) & ~1)+ (2 * COLOR_MARGINS))*dv;
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] = (((wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2]/dv) & ~1)+ (2 * COLOR_MARGINS))*dv;
......@@ -545,11 +543,11 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
// Modify sequence if one or 2 frames is skipped from top because of P_WOI_TOP
// Margins
if (flipX) {
wl= (thispars->pars[P_SENSOR_WIDTH]+dh*X313_MARGINS)-ww-wl; // simplified (ww includes margins*dh)
wl= (thispars->pars[P_SENSOR_WIDTH]+dh*(2 * COLOR_MARGINS))-ww-wl; // simplified (ww includes margins*dh)
if(wl < 0) wl = 0;
}
if (flipY) {
wt= (thispars->pars[P_SENSOR_HEIGHT]+dv*X313_MARGINS)-wh-wt; // simplified (wh includes margins*dv)
wt= (thispars->pars[P_SENSOR_HEIGHT]+dv*(2 * COLOR_MARGINS))-wh-wt; // simplified (wh includes margins*dv)
if(wt < 0) wt = 0;
}
if ((wt>height1) && (sequence >>2)) { // only skip if anything is left
......@@ -690,13 +688,13 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
if (flipY) multi_mode_flips ^= 0x2a;
MDF25(printk("sequence=0x%x flipX=%x flipY=%x multi_mode_flips=0x%x \n",sequence,flipX,flipY,multi_mode_flips ));
SETFRAMEPARS_COND(P_MULTI_MODE_FLIPS, multi_mode_flips);
// subtract X313_MARGINS from the first and last frame
// subtract (2 * COLOR_MARGINS) from the first and last frame
// SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK1, ((height1 - (X313_MARGINS>>1)*(((height2==0) && (height3==0))?2:1)) & 0xffff) | (vblank2<<16));
// SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK2, ((height2 - (X313_MARGINS>>1)*(((height2 >0) && (height3==0))?1:0)) & 0xffff) | (vblank3<<16));
// Currently X313_MARGINS (4 pixels) are subtracted from the very last sub-frame only
SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK1, ((height1 - X313_MARGINS*(((height2==0) && (height3==0))?1:0)) & 0xffff) | (vblank2<<16));
SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK2, ((height2 - X313_MARGINS*(((height2 >0) && (height3==0))?1:0)) & 0xffff) | (vblank3<<16));
// SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK1, ((height1 - ((2 * COLOR_MARGINS)>>1)*(((height2==0) && (height3==0))?2:1)) & 0xffff) | (vblank2<<16));
// SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK2, ((height2 - ((2 * COLOR_MARGINS)>>1)*(((height2 >0) && (height3==0))?1:0)) & 0xffff) | (vblank3<<16));
// Currently (2 * COLOR_MARGINS) (4 pixels) are subtracted from the very last sub-frame only
SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK1, ((height1 - (2 * COLOR_MARGINS)*(((height2==0) && (height3==0))?1:0)) & 0xffff) | (vblank2<<16));
SETFRAMEPARS_COND(P_MULTI_HEIGHT_BLANK2, ((height2 - (2 * COLOR_MARGINS)*(((height2 >0) && (height3==0))?1:0)) & 0xffff) | (vblank3<<16));
if (GLOBALPARS(sensor_port, G_MULTI_CFG) & (1 <<G_MULTI_CFG_BEFORE)) {
//TODO: Program 10359 registers here
......@@ -935,6 +933,8 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
{
struct frameparspair_t pars_to_update[64]; // so far 39 actually needed
int nupdate=0;
x393_sensio_ctl_t sensio_ctl = {.d32=0};
x393_camsync_mode_t camsync_mode = {.d32=0};
unsigned long bitstream_version;
unsigned long sensor_id[MAX_SENSORS];
......@@ -943,7 +943,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
int this_sensor_type;
// .hact_delay = -2500, // -2.5ns delay in ps
// .sensorDelay = 2460, // Delay from sensor clock at FPGA output to pixel data transition (FPGA input), short cable (ps)
multi_unitialized=0; // reset this static variable - it will prevent copying individual flips to multiple until copmosite mode is used
multi_unitialized=0; // reset this static variable - it will prevent copying individual flips to multiple until composite mode is used
MDF3(printk(" frame16=%d\n",frame16));
GLOBALPARS(sensor_port,G_SENS_AVAIL)=0; // no 10359A board present
if (frame16 >= 0) return -1; // can only work in ASAP mode
......@@ -975,8 +975,13 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
printk("10353 sensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]);
udelay (100);// 0.0001 sec to stabilize clocks
X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset
X3X3_SENSDCM_CLK2X_RESET; // reset pclk2x DCM also
// X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset
// X3X3_SENSDCM_CLK2X_RESET; // reset pclk2x DCM also
// NC393 reset mmcm - is it needed? Clock was not changed yet
sensio_ctl.mmcm_rst = 1;
sensio_ctl.mmcm_rst_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
// reset system and SDRAM DCMs on 10359
MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SYSTEM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
......@@ -1005,10 +1010,15 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
// Try to read chip version from each of the 3 possible sensors
printk("removing MRST from the sensor\n");
//
CCAM_NEGRST; // set negative MRST polarity
CCAM_TRIG_INT;
CCAM_MRST_OFF;
CCAM_ARST_OFF;
sensio_ctl.d32 = 0;
sensio_ctl.mrst = 1;
sensio_ctl.mrst_set = 1;
sensio_ctl.arst = 1;
sensio_ctl.arst_set = 1;
x393_sensio_ctrl(sensio_ctl,sensor_port);
camsync_mode.trig = 0;
camsync_mode.trig_set = 1;
x393_camsync_mode (camsync_mode);
udelay (100);
GLOBALPARS(sensor_port,G_SENS_AVAIL) |= 1<< (GLOBALPARS(sensor_port,G_SENS_AVAIL)); // temporary to indicate sensor detection functions that they need to initialize multisensor registers
......@@ -1142,9 +1152,10 @@ Now overwrite sensor functions with it's own (originals (physical sensor ones) a
SETFRAMEPARS_SET(P_MULTI_HEIGHT2, 1940);
SETFRAMEPARS_SET(P_MULTI_HEIGHT3, 1940);
#ifdef NC353
CCAM_RESET_MCONTR_ON ; // Set mode that resets memory controller pointers after each frame sync. TODO: Later - make it work without?
CCAM_ENDFRAMES_EN ; // Enable ending frame being compressed if no more data will be available (frame ended before specified number of blocks compressed)
#endif
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
return this_sensor_type;
}
......@@ -1295,7 +1306,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
int multi_frame=0;
if (composite && SENSOR_IN_SEQ_EN(1,sequence,sensor_mask)) { // specified in sequence is enabled
multi_frame=1;
total_height+=(vblank+X313_MARGINS)*dv;
total_height+=(vblank+(2 * COLOR_MARGINS))*dv;
MDF25(printk(" total_height=0x%x\n",total_height));
if (!height2) height2=sensor->imageHeight;
if (height2 < sensor->minHeight) height2=sensor->minHeight;
......@@ -1305,7 +1316,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
total_height+=height2;
MDF25(printk(" total_height=0x%x\n",total_height));
if (SENSOR_IN_SEQ_EN(2,sequence,sensor_mask)) {
total_height+=(vblank+X313_MARGINS)*dv;
total_height+=(vblank+(2 * COLOR_MARGINS))*dv;
MDF25(printk(" total_height=0x%x\n",total_height));
if (!height3) height3=sensor->imageHeight;
if (height3 < sensor->minHeight) height3=sensor->minHeight;
......
......@@ -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
......
......@@ -210,17 +210,9 @@
#include "pgm_functions.h"
#include "jpeghead.h" // to program FPGA Huffman tables
#include "x393.h"
// #include "legacy_defines.h" // temporarily
#include "sensor_i2c.h"
#include "x393_videomem.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