Commit 804b8db1 authored by Andrey Filippov's avatar Andrey Filippov

added detect_sensor module

parent 4f108db9
...@@ -32,3 +32,4 @@ obj-$(CONFIG_ELPHEL393) += imu_log393.o ...@@ -32,3 +32,4 @@ obj-$(CONFIG_ELPHEL393) += imu_log393.o
obj-$(CONFIG_ELPHEL393) += cxi2c.o obj-$(CONFIG_ELPHEL393) += cxi2c.o
obj-$(CONFIG_ELPHEL393) += x393_videomem.o obj-$(CONFIG_ELPHEL393) += x393_videomem.o
obj-$(CONFIG_ELPHEL393) += detect_sensors.o
\ No newline at end of file
This diff is collapsed.
/***************************************************************************//**
* @file detect_sensors.h
* @brief Determine sensor boards attached to each of the ports. Use
* Device Tree, sysfs to set sensor types per port. Add autodetection
* (using pullup/pull downs) later
* @copyright Copyright 2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#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
int get_code_by_name(const char * name, int type);
const char * get_name_by_code(int code, int type);
int get_detected_mux_code(int port);
int get_detected_sensor_code(int port, int sub_chn);
int set_detected_mux_code(int port, int mux_type);
int set_detected_sensor_code(int port, int sub_chn, int mux_type);
...@@ -210,10 +210,17 @@ ...@@ -210,10 +210,17 @@
#include "pgm_functions.h" #include "pgm_functions.h"
#include "jpeghead.h" // to program FPGA Huffman tables #include "jpeghead.h" // to program FPGA Huffman tables
#include "x393.h" #include "x393.h"
#include "legacy_defines.h" // temporarily // #include "legacy_defines.h" // temporarily
#include "sensor_i2c.h" #include "sensor_i2c.h"
#include "x393_videomem.h" #include "x393_videomem.h"
#define COLOR_MARGINS 2 // add this many pixels each side #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
/** /**
* @brief optional debug output macros * @brief optional debug output macros
...@@ -356,7 +363,10 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -356,7 +363,10 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
if (thispars->pars[P_SENSOR]) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0) if (thispars->pars[P_SENSOR]) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0)
// no other initializations, just the sensor-related stuff (starting with lowest sensor clock) // no other initializations, just the sensor-related stuff (starting with lowest sensor clock)
// stop hardware i2c controller, so it will not get stuck when waiting for !busy // stop hardware i2c controller, so it will not get stuck when waiting for !busy
#ifndef NC353
// NC393 - nothing to do here - use a separate module for sensor setup: DT, sysfs, something else (add pin pullup/down)
return 0;
#else
// NOTE: disabling interrupts here !!! // NOTE: disabling interrupts here !!!
camera_interrupts (0); camera_interrupts (0);
...@@ -376,13 +386,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -376,13 +386,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
// Need to set slow clock // Need to set slow clock
// f1=imageParamsR[P_CLK_SENSOR]=20000000; setClockFreq(1, imageParamsR[P_CLK_SENSOR]); X3X3_RSTSENSDCM; // f1=imageParamsR[P_CLK_SENSOR]=20000000; setClockFreq(1, imageParamsR[P_CLK_SENSOR]); X3X3_RSTSENSDCM;
#ifdef NC353
was_sensor_freq=getClockFreq(1); // using clock driver data, not thispars was_sensor_freq=getClockFreq(1); // using clock driver data, not thispars
setFramePar(sensor_port, thispars, P_CLK_FPGA, getClockFreq(0)); // just in case - read the actual fpga clock frequency and store it (no actions) setFramePar(sensor_port, thispars, P_CLK_FPGA, getClockFreq(0)); // just in case - read the actual fpga clock frequency and store it (no actions)
setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000);
setClockFreq(1, thispars->pars[P_CLK_SENSOR]); setClockFreq(1, thispars->pars[P_CLK_SENSOR]);
printk("\nsensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]); printk("\nsensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]);
#endif
udelay (100);// 0.0001 sec to stabilize clocks udelay (100);// 0.0001 sec to stabilize clocks
X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset
X3X3_SENSDCM_CLK2X_RESET; // reset pclk2x DCM also X3X3_SENSDCM_CLK2X_RESET; // reset pclk2x DCM also
...@@ -402,12 +410,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -402,12 +410,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
printk("removing MRST from the sensor\n"); printk("removing MRST from the sensor\n");
CCAM_MRST_OFF; CCAM_MRST_OFF;
} }
#ifdef CONFIG_ETRAX_ELPHEL_MT9X001
if (thispars->pars[P_SENSOR]==0) { if (thispars->pars[P_SENSOR]==0) {
mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type
printk("trying MT9P001\n"); printk("trying MT9P001\n");
} }
#endif
// temporary - disabling old sensors // temporary - disabling old sensors
#define ENABLE_OLD_SENSORS 1 #define ENABLE_OLD_SENSORS 1
#ifdef ENABLE_OLD_SENSORS #ifdef ENABLE_OLD_SENSORS
...@@ -501,8 +508,10 @@ printk ("Inverted MRST\n"); ...@@ -501,8 +508,10 @@ printk ("Inverted MRST\n");
// NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later) // NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later)
// Here interrupts are disabled - with camera_interrupts (0) earlier in this function) // Here interrupts are disabled - with camera_interrupts (0) earlier in this function)
camera_interrupts (1); camera_interrupts (1);
return 0; return 0;
#endif
} }
...@@ -884,9 +893,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -884,9 +893,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
if ((!oversize) && (width > sensor_width)) width= sensor_width; if ((!oversize) && (width > sensor_width)) width= sensor_width;
// make width to be multiple of the compressor tile (before adding margins of 4 pixels) // make width to be multiple of the compressor tile (before adding margins of 4 pixels)
width= (((width/dh) + timestamp_len)/X313_TILEHOR)*X313_TILEHOR-timestamp_len; // divided by dh width= (((width/dh) + timestamp_len)/X393_TILEHOR)*X393_TILEHOR-timestamp_len; // divided by dh
// suppose minimal width refers to decimated output // suppose minimal width refers to decimated output
while (width < sensor->minWidth) width+=X313_TILEHOR; while (width < sensor->minWidth) width+=X393_TILEHOR;
if (unlikely(thispars->pars[P_ACTUAL_WIDTH] != (width+timestamp_len))) { if (unlikely(thispars->pars[P_ACTUAL_WIDTH] != (width+timestamp_len))) {
SETFRAMEPARS_SET(P_ACTUAL_WIDTH, width+timestamp_len); ///full width for the compressor, including timestamp, but excluding margins SETFRAMEPARS_SET(P_ACTUAL_WIDTH, width+timestamp_len); ///full width for the compressor, including timestamp, but excluding margins
} }
...@@ -902,7 +911,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -902,7 +911,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
if(pfh > 0) { if(pfh > 0) {
if (pfh < sensor->minHeight) pfh = sensor->minHeight; if (pfh < sensor->minHeight) pfh = sensor->minHeight;
if (pfh & 1) pfh++; if (pfh & 1) pfh++;
if (height > X313_MAXHEIGHT*dv) height=X313_MAXHEIGHT*dv; if (height > X393_MAXHEIGHT*dv) height=X393_MAXHEIGHT*dv;
pf_stripes = height / (pfh * dv); pf_stripes = height / (pfh * dv);
if(pf_stripes < 1) pf_stripes = 1; if(pf_stripes < 1) pf_stripes = 1;
if (unlikely(thispars->pars[P_SENSOR_PIXV] != pfh)) { if (unlikely(thispars->pars[P_SENSOR_PIXV] != pfh)) {
...@@ -911,9 +920,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -911,9 +920,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
} }
} else { } else {
if ((!oversize ) && (height > sensor_height)) height=sensor_height; if ((!oversize ) && (height > sensor_height)) height=sensor_height;
height= ((height/dv)/X313_TILEVERT) * X313_TILEVERT; // divided by dv (before multisensor options) height= ((height/dv)/X393_TILEVERT) * X393_TILEVERT; // divided by dv (before multisensor options)
// suppose minimal height refers to decimated output // suppose minimal height refers to decimated output
while (height < sensor->minHeight) height+=X313_TILEVERT; while (height < sensor->minHeight) height+=X393_TILEVERT;
if (unlikely(thispars->pars[P_SENSOR_PIXV] != height+(2 * COLOR_MARGINS))) if (unlikely(thispars->pars[P_SENSOR_PIXV] != height+(2 * COLOR_MARGINS)))
SETFRAMEPARS_SET(P_SENSOR_PIXV, height+(2 * COLOR_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
height*=dv; height*=dv;
......
//pgm_functions.h /***************************************************************************//**
///extern struct sensorproc_t * sensorproc; * @file pgm_functions.h
* @brief Sensor/FPGA programming functions, called from IRQ/tasklet in
* response to the parameter changes
* @copyright Copyright 2008-2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "sensor_i2c.h" #include "sensor_i2c.h"
......
...@@ -497,9 +497,9 @@ static int videomem_probe(struct platform_device *pdev) ...@@ -497,9 +497,9 @@ static int videomem_probe(struct platform_device *pdev)
dev_dbg(dev, "Registering character device with name "VIDEOMEM_DRIVER_NAME); dev_dbg(dev, "Registering character device with name "VIDEOMEM_DRIVER_NAME);
res = register_chrdev(LOGGER_MAJOR, VIDEOMEM_DRIVER_NAME, &videomem_fops); res = register_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME, &videomem_fops);
if(res < 0) { if(res < 0) {
dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",VIDEOMEM_MAJOR); dev_err(dev, "\videomem_probe: couldn't get a major number %d.\n ",VIDEOMEM_MAJOR);
return res; return res;
} }
// Setup interrupt // Setup interrupt
...@@ -513,13 +513,13 @@ static int videomem_probe(struct platform_device *pdev) ...@@ -513,13 +513,13 @@ static int videomem_probe(struct platform_device *pdev)
dev_err(dev, "can not allocate interrupts for %s\n","membridge_irq"); dev_err(dev, "can not allocate interrupts for %s\n","membridge_irq");
return -EBUSY; return -EBUSY;
} }
init_waitqueue_head(&videomem_wait_queue); // wait queue for logger init_waitqueue_head(&videomem_wait_queue); // wait queue for video memory driver
g_dev_ptr = dev; // for debugfs g_dev_ptr = dev; // for debugfs
return 0; return 0;
} }
/** IMU/GPS logger driver remove function */ /** Video memory driver remove function */
static int videomem_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure static int videomem_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure
///< @return always 0 ///< @return always 0
{ {
......
...@@ -224,15 +224,22 @@ ...@@ -224,15 +224,22 @@
// leave it here - may be used in user applications // leave it here - may be used in user applications
#define SENSOR_MASK 0xfc ///< Mask to apply for distinguish between different sensor groups (of similar devices) #define SENSOR_MASK 0xfc ///< Mask to apply for distinguish between different sensor groups (of similar devices)
#define SENSOR_DETECT 0x00 ///< Unknown sensor, try to autodetect
#define SENSOR_ZR32112 0x04 ///< Zoran ZR32112 #define SENSOR_ZR32112 0x04 ///< Zoran ZR32112
#define SENSOR_ZR32212 0x08 ///< Zoran ZR32212 #define SENSOR_ZR32212 0x08 ///< Zoran ZR32212
#define SENSOR_KAC1310 0x20 ///< Kodak KAC1310 #define SENSOR_KAC1310 0x20 ///< Kodak KAC1310
#define SENSOR_KAC5000 0x24 ///< Kodak KAC5000 #define SENSOR_KAC5000 0x24 ///< Kodak KAC5000
#define SENSOR_MI1300 0x30 ///< Micron MI1300 #define SENSOR_MI1300 0x30 ///< Micron MI1300
#define SENSOR_MT9X001 0x30 ///< Micron: MT9M001 - 31, MT9D001 - 32, MT9T001 - 33, MT9P001 - 34 #define SENSOR_MT9X001 0x30 ///< Micron: MT9M001 - 31, MT9D001 - 32, MT9T001 - 33, MT9P001 - 34
#define SENSOR_MT9Y001 0x34 ///< Micron/Aptina/Onsemi MT9P001 - 34 #define SENSOR_MT9M001 0x31 ///< MT9M001
#define SENSOR_MT9D001 0x32 ///< MT9D001
#define SENSOR_MT9T001 0x33 ///< MT9T001
#define SENSOR_MT9P006 0x34 ///< MT9P006
#define SENSOR_MT9F002 0x38 ///< MT9F002
//#define SENSOR_MT9Y001 0x34 ///< Micron/Aptina/Onsemi MT9P001 - 34
#define SENSOR_IBIS51300 0x40 ///< FillFactory IBIS51300 #define SENSOR_IBIS51300 0x40 ///< FillFactory IBIS51300
#define SENSOR_KAI11000 0x80 ///< Kodak KAI11002 #define SENSOR_KAI11000 0x80 ///< Kodak KAI11002
#define SENSOR_MUX_10359 0xe0 ///< Sensor multiplexer 10359
#define SENSOR_NONE 0xfc ///< No sensor present #define SENSOR_NONE 0xfc ///< No sensor present
// sensor sizes: // sensor sizes:
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define IMAGEACQ_MAJOR 140 #define IMAGEACQ_MAJOR 140
#define LOGGER_MAJOR 141 #define LOGGER_MAJOR 141
#define VIDEOMEM_MAJOR 142 // implement raw access to memory and/or 16-bit image buffers over membridge interface #define VIDEOMEM_MAJOR 142 // implement raw access to memory and/or 16-bit image buffers over membridge interface
#define DETECT_SENSORS_MAJOR 143 // Maybe not needed?
/// MINORS /// MINORS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment