Commit cf4af6f5 authored by Andrey Filippov's avatar Andrey Filippov

More editing

parent 804b8db1
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
/** Wait queue for the processes waiting for a new frame to appear in the circular buffer */ /** Wait queue for the processes waiting for a new frame to appear in the circular buffer */
wait_queue_head_t circbuf_wait_queue; 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; struct circbuf_priv_t *circbuf_priv_ptr = circbuf_priv;
static struct device *g_dev_ptr; static struct device *g_dev_ptr;
...@@ -109,7 +109,7 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) ...@@ -109,7 +109,7 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
// set circular buffer size in bytes // set circular buffer size in bytes
set_globalParam(G_CIRCBUFSIZE, CCAM_DMA_SIZE); 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].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; 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 * ...@@ -572,10 +572,10 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
/* debug code follows*/ /* debug code follows*/
switch (buf[0] - 0x30) { switch (buf[0] - 0x30) {
case 0: case 0:
camera_interrupts(0); compressor_interrupts(0,chn);
break; break;
case 1: case 1:
camera_interrupts(1); compressor_interrupts(1,chn);
break; break;
} }
/* debug code end */ /* debug code end */
......
...@@ -753,10 +753,10 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t * ...@@ -753,10 +753,10 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
/* debug code follows*/ /* debug code follows*/
switch (buf[0] - 0x30) { switch (buf[0] - 0x30) {
case 0: case 0:
camera_interrupts(0); compressor_interrupts(0,chn);
break; break;
case 1: case 1:
camera_interrupts(1); compressor_interrupts(1,chn);
break; break;
case 3: case 3:
/* update image quality */ /* update image quality */
......
...@@ -60,25 +60,29 @@ struct sensor_name_t { ...@@ -60,25 +60,29 @@ struct sensor_name_t {
const char * name; const char * name;
u32 code; u32 code;
int type; ///< +1 - applicable to sensors, +2 - applicable to multiplexers 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[] ={ const struct sensor_name_t sensor_names[] ={
{.name="detect", .type=3, .code = 0}, // to be automatically detected {.name="detect", .type=3, .iface=NONE, .code = 0}, // to be automatically detected
{.name="none", .type=3, .code = SENSOR_NONE}, // no device attached {.name="none", .type=3, .iface=NONE, .code = SENSOR_NONE}, // no device attached
{.name="mux10359", .type=2, .code = SENSOR_MUX_10359}, // no device attached {.name="mux10359", .type=2, .iface=PARALLEL12, .code = SENSOR_MUX_10359}, // no device attached
{.name="zr32112", .type=1, .code = SENSOR_ZR32112}, // Zoran ZR32112 {.name="zr32112", .type=1, .iface=PARALLEL12, .code = SENSOR_ZR32112}, // Zoran ZR32112
{.name="zr32212", .type=1, .code = SENSOR_ZR32212}, // Zoran ZR32212 {.name="zr32212", .type=1, .iface=PARALLEL12, .code = SENSOR_ZR32212}, // Zoran ZR32212
{.name="kac1310", .type=1, .code = SENSOR_KAC1310}, // Kodak KAC1310 {.name="kac1310", .type=1, .iface=PARALLEL12, .code = SENSOR_KAC1310}, // Kodak KAC1310
{.name="kac5000", .type=1, .code = SENSOR_KAC5000}, // Kodak KAC5000 {.name="kac5000", .type=1, .iface=PARALLEL12, .code = SENSOR_KAC5000}, // Kodak KAC5000
{.name="mi1300", .type=1, .code = SENSOR_MI1300}, // Micron MI1300 {.name="mi1300", .type=1, .iface=PARALLEL12, .code = SENSOR_MI1300}, // Micron MI1300
{.name="mt9m001", .type=1, .code = SENSOR_MT9M001}, // MT9M001 {.name="mt9m001", .type=1, .iface=PARALLEL12, .code = SENSOR_MT9M001}, // MT9M001
{.name="mt9d001", .type=1, .code = SENSOR_MT9D001}, // MT9D001 {.name="mt9d001", .type=1, .iface=PARALLEL12, .code = SENSOR_MT9D001}, // MT9D001
{.name="mt9t001", .type=1, .code = SENSOR_MT9T001}, // MT9T001 {.name="mt9t001", .type=1, .iface=PARALLEL12, .code = SENSOR_MT9T001}, // MT9T001
{.name="mt9p006", .type=1, .code = SENSOR_MT9P006}, // MT9P006 {.name="mt9p006", .type=1, .iface=PARALLEL12, .code = SENSOR_MT9P006}, // MT9P006
{.name="mt9f002", .type=1, .code = SENSOR_MT9F002}, // MT9F002 {.name="mt9f002", .type=1, .iface=HISPI4, .code = SENSOR_MT9F002}, // MT9F002
{.name="ibis51300", .type=1, .code = SENSOR_IBIS51300}, // FillFactory IBIS51300 {.name="ibis51300", .type=1, .iface=PARALLEL12, .code = SENSOR_IBIS51300}, // FillFactory IBIS51300
{.name="kai11002", .type=1, .code = SENSOR_KAI11000}, // Kodak KAI11002 {.name="kai11002", .type=1, .iface=PARALLEL12, .code = SENSOR_KAI11000}, // Kodak KAI11002
{.name=NULL, .type=0, .code = 0} // end of list {.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_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 //#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 ...@@ -111,6 +115,20 @@ const char * get_name_by_code(int code, ///< sensor code
return NULL; 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 */ /** Get sensor port multiplexer type */
int get_detected_mux_code(int port) ///< Sensor port number (0..3) 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) ...@@ -120,12 +138,59 @@ int get_detected_mux_code(int port) ///< Sensor port number (0..3)
} }
/** Get sensor type */ /** Get sensor type */
int get_detected_sensor_code(int port, ///< Sensor port number (0..3) 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 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 */ /** Set sensor port multiplexer type */
int set_detected_mux_code(int port, ///< Sensor port number (0..3) 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) 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) ...@@ -138,6 +203,7 @@ int set_detected_mux_code(int port, ///< Sensor port number (0..3)
return -EINVAL; return -EINVAL;
} }
sensorPortConfig[port & 3].mux = mux_type; sensorPortConfig[port & 3].mux = mux_type;
update_port_iface(port);
return 0; return 0;
} }
...@@ -154,6 +220,7 @@ int set_detected_sensor_code(int port, ///< Sensor port number (0..3) ...@@ -154,6 +220,7 @@ int set_detected_sensor_code(int port, ///< Sensor port number (0..3)
return -EINVAL; return -EINVAL;
} }
sensorPortConfig[port & 3].sensor[sub_chn] = sens_type; sensorPortConfig[port & 3].sensor[sub_chn] = sens_type;
update_port_iface(port);
return 0; return 0;
} }
...@@ -182,7 +249,7 @@ static int get_channel_sub_from_name(struct device_attribute *attr) ///< Linux k ...@@ -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) static ssize_t show_port_mux(struct device *dev, struct device_attribute *attr, char *buf)
{ {
int i; 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); if (name) return sprintf(buf,"%s\n", name);
// Should never get here // Should never get here
return sprintf(buf,"0x%x\n", sensorPortConfig[get_channel_from_name(attr)].mux); 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 ...@@ -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 psch = get_channel_sub_from_name(attr);
int port = (psch>>4) &3; int port = (psch>>4) &3;
int sub_chn = psch &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); if (name) return sprintf(buf,"%s\n", name);
// Should never get here // Should never get here
return sprintf(buf,"0x%x\n", sensorPortConfig[(psch>>4) & 3].sensor[psch & 3]); return sprintf(buf,"0x%x\n", sensorPortConfig[(psch>>4) & 3].sensor[psch & 3]);
......
...@@ -20,9 +20,15 @@ ...@@ -20,9 +20,15 @@
#define DETECT_SENSOR 1 ///< Include sensors, May be OR-ed when looking for sensor/multiplexer code/name #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 #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); int get_code_by_name(const char * name, int type);
const char * get_name_by_code(int code, 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_mux_code(int port);
int get_detected_sensor_code(int port, int sub_chn); 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_mux_code(int port, int mux_type);
int set_detected_sensor_code(int port, int sub_chn, 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 ...@@ -146,7 +146,7 @@ wait_queue_head_t aframepars_wait_queue[SENSOR_PORTS];// used to wait for
/* Remove after compilation OK */ /* Remove after compilation OK */
struct sensorproc_t * sensorproc = NULL; struct sensorproc_t * sensorproc = NULL;
//void camera_interrupts (int on) {} //void compressor_interrupts (int on) {}
#if 0 #if 0
#define wait_event_interruptible(wq, condition) \ #define wait_event_interruptible(wq, condition) \
({ \ ({ \
...@@ -353,6 +353,16 @@ inline unsigned long get_imageParamsPrev(int sensor_port, int n) ...@@ -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]; 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) * @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; * 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) ...@@ -1181,11 +1191,12 @@ loff_t framepars_lseek(struct file * file, loff_t offset, int orig)
break; break;
case LSEEK_INTERRUPT_OFF: // disable camera interrupts case LSEEK_INTERRUPT_OFF: // disable camera interrupts
MDF2(printk("LSEEK_INTERRUPT_OFF\n")); MDF2(printk("LSEEK_INTERRUPT_OFF\n"));
camera_interrupts(0); // compressor_interrupts(0,sensor_port);
sensor_interrupts(0,sensor_port);
break; break;
case LSEEK_INTERRUPT_ON: // enable camera interrupts case LSEEK_INTERRUPT_ON: // enable camera interrupts
MDF2(printk("LSEEK_INTERRUPT_ON\n")); // MDF2(printk("LSEEK_INTERRUPT_ON\n"));
camera_interrupts(1); sensor_interrupts(1,sensor_port);
break; break;
} }
} }
......
...@@ -21,6 +21,8 @@ void resetFrameNumber (int sensor_port); /// reset this frame number (called fr ...@@ -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_imageParamsThis (int sensor_port, int n);
unsigned long get_imageParamsPrev (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); void set_imageParamsThis (int sensor_port, int n, unsigned long d);
unsigned long get_globalParam (int sensor_port, int n); unsigned long get_globalParam (int sensor_port, int n);
......
...@@ -113,8 +113,6 @@ ...@@ -113,8 +113,6 @@
//#include "fpga_io.h"//fpga_table_write_nice //#include "fpga_io.h"//fpga_table_write_nice
#include "framepars.h" // for debug mask #include "framepars.h" // for debug mask
#include <elphel/elphel393-mem.h> #include <elphel/elphel393-mem.h>
#include "legacy_defines.h" // temporarily
//#include "cc3x3.h"
#include "x393.h" #include "x393.h"
#include "histograms.h" #include "histograms.h"
......
...@@ -55,8 +55,6 @@ ...@@ -55,8 +55,6 @@
#include "imu_log393.h" #include "imu_log393.h"
#include "x393.h" #include "x393.h"
#include "cci2c.h" #include "cci2c.h"
//#include "legacy_defines.h" // temporarily
#if 0 #if 0
#define D(x) x #define D(x) x
......
This diff is collapsed.
This diff is collapsed.
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#define I2C359_CLK_NUMBER 4 ///< OK with NC393, clock is ANDed with 3
//multisensor.h //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 //#define I2C359_INC 2 //< slave address increment between sensors in 10359A board (broadcast, 1,2,3) (7 bits SA) moved to sensor_common
......
This diff is collapsed.
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
*******************************************************************************/ *******************************************************************************/
#include "sensor_i2c.h" #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 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 )); int add_sensor_proc(int index, int (*sens_func)(int sensor_port, struct sensor_t * , struct framepars_t * , struct framepars_t *, int ));
......
This diff is collapsed.
...@@ -15,6 +15,11 @@ extern struct sensorproc_t * sensorproc; ...@@ -15,6 +15,11 @@ extern struct sensorproc_t * sensorproc;
#ifdef CONFIG_ETRAX_ELPHEL_MT9X001 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
#include "mt9x001.h" #include "mt9x001.h"
#endif #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" //#include "multisensor.h"
//int camSeqGetJPEG_wp(void); //int camSeqGetJPEG_wp(void);
//int camSeqGetJPEG_rp(void); //int camSeqGetJPEG_rp(void);
...@@ -36,7 +41,9 @@ extern unsigned long * ccam_dma_buf_ptr[SENSOR_PORTS]; ...@@ -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??) //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) ///can be verified with if (!X313_IS_SDRAM_ON)
void reset_compressor(unsigned int chn); 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); 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) ///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)
......
...@@ -76,6 +76,50 @@ static int sysfs_page[4]; ///< when positive - page locked for exclus ...@@ -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 struct device *sdev = NULL; ///< store this device here
static u32 i2c_read_data[4]; ///< last data read from i2c device 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 */ /** Mark all i2c pages for each channel as free */
void i2c_page_alloc_init(void) void i2c_page_alloc_init(void)
{ {
......
...@@ -17,6 +17,14 @@ ...@@ -17,6 +17,14 @@
#ifndef SENSOR_I2C_H #ifndef SENSOR_I2C_H
#define 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*/ /** I2C device description to be used with i2c sequencer*/
typedef struct{ typedef struct{
char name[32]; ///< Device class name (up to 31 characters) char name[32]; ///< Device class name (up to 31 characters)
...@@ -27,136 +35,29 @@ typedef struct{ ...@@ -27,136 +35,29 @@ typedef struct{
int scl_khz; ///< maximal SCL frequency in KHz (currently limited by 200KHz slowest) int scl_khz; ///< maximal SCL frequency in KHz (currently limited by 200KHz slowest)
} x393_i2c_device_t; } x393_i2c_device_t;
/** Reserve i2c page (1 of 256) for a sensor port int i2c_stop_run_reset(int chn, int cmd);
* @param chn sensor port number (0..3) */ int i2c_drive_mode (int chn, int sda_drive_high, int sda_release);
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 write_xi2c_abs (int chn, int i2c_page_alloc (int chn);
int offs, // 4 bits int i2c_page_register(int chn, int page);
u32 * data); void i2c_page_free (int chn, int page);
/* 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 */
x393_i2c_device_t * xi2c_dev_get(const char * name); x393_i2c_device_t * xi2c_dev_get(const char * name);
void set_xi2c_raw (int chn, int page, u32 data);
/* Single-command i2c write/read register using pre-defined device classes */ void set_xi2c_wr (int chn,int page, int sa7, int rah, int num_bytes, int bit_delay);
int x393_xi2c_write_reg(const char * cname, // device class name void set_xi2c_wrc (x393_i2c_device_t * dc, int chn, int page, int rah);
int chn, // sensor port number void set_xi2c_rdc (x393_i2c_device_t * dc, int chn, int page);
int sa7_offs, // slave address (7-bit) offset from the class defined slave address void set_xi2c_rd (int chn, int page, int two_byte_addr, int num_bytes, int bit_delay);
int reg_addr, // register address (width is defined by class) int write_xi2c_rel (int chn, int offs, u32 * data);
int data); // data to write (width is defined by class) int write_xi2c_abs (int chn, int offs, u32 * data);
void write_xi2c_reg16 (int chn, int page, int addr, u32 data);
int x393_xi2c_read_reg( const char * cname, // device class name void write_xi2c_reg16_rel (int chn, int page, int frame, int addr, u32 data);
int chn, // sensor port number void write_xi2c_reg16_abs (int chn, int page, int frame, int addr, u32 data);
int sa7_offs, // slave address (7-bit) offset from the class defined slave address void write_xi2c_reg16_abs_asap (int chn, int page, int frame, int addr, u32 data);
int reg_addr, // register address (width is defined by class) void read_xi2c (x393_i2c_device_t * dc, int chn, int page, int addr);
int * datap); // pointer to a data receiver (read data width is defined by class) void read_xi2c_sa7 (int chn, int page, int sa7, int addr);
int legacy_read_i2c_reg(int chn, // sensor port number int read_xi2c_fifo (int chn);
int page, // i2c table page registerd for read operation x393_i2c_device_t * xi2c_dev_get(const char * name);
int sa7, // slave address (7-bit) of the device int x393_xi2c_write_reg(const char * cname, int chn, int sa7_offs, int reg_addr, int data);
// Offset is non-zero when multiple devices of the same class are present. int x393_xi2c_read_reg (const char * cname, int chn, int sa7_offs, int reg_addr, int * datap);
int reg_addr, // register address (width is defined by class) int legacy_read_i2c_reg(int chn, int page, int sa7, int reg_addr, int len, int * datap);
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)
#endif #endif
...@@ -18,3 +18,7 @@ ...@@ -18,3 +18,7 @@
#include "x393_fpga_functions.h" #include "x393_fpga_functions.h"
int init_command_sequencer(int sensor_port)
{
return 0;
}
...@@ -387,6 +387,7 @@ ...@@ -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_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_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 #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_TEMPERATURE_PERIOD 75 ///< period of temperature measurements, ms (normally - multiple seconds)