Commit 732ab22a authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

merged with rocko

parent a63ae561
......@@ -203,7 +203,7 @@ ssize_t circbuf_get_ptr(int sensor_port, size_t offset, size_t len, struct fvec
return ret;
}
EXPORT_SYMBOL_GPL(circbuf_get_ptr);
EXPORT_SYMBOL_GPL(circbuf_get_ptr); // @suppress("Unused function declaration") it is still needed
/**
* @brief Process circular buffer file opening and define further action in accordance
......@@ -1026,7 +1026,7 @@ static struct platform_driver elphel393_circbuf = {
},
};
module_platform_driver(elphel393_circbuf);
module_platform_driver(elphel393_circbuf); // @suppress("Unused variable declaration in file scope") because
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
......
......@@ -100,7 +100,6 @@
//#include <linux/of_fdt.h>
//#include <linux/of_net.h>
#include <linux/sysfs.h>
#include <linux/uaccess.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
......
......@@ -37,6 +37,7 @@
#include "mt9x001.h"
#include "mt9f002.h"
#include "multi10359.h"
#include "lepton.h"
#include "detect_sensors.h"
#define DETECT_SENSORS_MODULE_DESCRIPTION "Detect sensor type(s) attached to each of the ports"
......@@ -78,6 +79,7 @@ const struct sensor_name_t sensor_names[] ={
{.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="lepton35", .type=1, .iface=VOSPI, .code = SENSOR_LEPTON35}, // Kodak KAI11002
{.name=NULL, .type=0, .iface=NONE, .code = 0} // end of list
};
static sens_iface_t port_iface[SENSOR_PORTS];
......@@ -182,7 +184,8 @@ void update_port_iface(int port) ///< Sensor port number (0..3)
port_iface[port] = iface;
return;
}
port_iface[port] = get_iface_by_code(get_detected_sensor_code(port,-1), DETECT_MUX); // '-1' - any subchannel
//TODO: Check with 10359. was port_iface[port] = get_iface_by_code(get_detected_sensor_code(port,-1), DETECT_MUX);
port_iface[port] = get_iface_by_code(get_detected_sensor_code(port,-1), DETECT_SENSOR); // '-1' - any subchannel
}
/** Get per-port interface type */
......@@ -369,6 +372,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
char names[4][80];
struct device_node *node = pdev->dev.of_node;
int num_ports, port, num_sub, sub_chn;
int scode;
if (node) {
config_string = of_get_property(node, OF_PREFIX_NAME",port-mux", NULL); // &len);
pr_info ("Mux config_string = %s (was looking for '%s')\n",config_string, OF_PREFIX_NAME",port-mux");
......@@ -396,6 +400,10 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
num_sub = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
pr_info ("port %d : %d subchannels\n",port, num_sub);
for (sub_chn = 0; sub_chn < num_sub; sub_chn++){
scode = get_code_by_name(names[sub_chn], DETECT_SENSOR);
if (scode < 0){
pr_err("Invalid sensor/mux name found in device tree: %s\n",names[sub_chn]);
}
pr_info ("Setting sensor %d:%d '%s' (0x%x)\n",port, sub_chn, names[sub_chn], get_code_by_name(names[sub_chn], DETECT_SENSOR));
set_detected_sensor_code(port, sub_chn, get_code_by_name(names[sub_chn], DETECT_SENSOR));
init_port_ahead_table(port,sub_chn);
......@@ -458,7 +466,7 @@ int detect_sensors_par2addr_init(int port,int sub_chn){
u16 haddr2rec[MAX_SENSORS][MAX_FPGA_RECS]; ///< Big LUT (but almost empty). Sensor's page address (haddr of reg addr) to fpga i2c record number (fpga line#)
};
*/
dev_info(g_dev_ptr,"detect_sensors_par2addr_init(): sensorPortConfig[%d].sensor[%d] = 0x%x\n",port, sub_chn, sensorPortConfig[port].sensor[sub_chn]);
switch (sensorPortConfig[port].sensor[sub_chn]) {
case SENSOR_MT9P006:
// get sensor table
......@@ -472,6 +480,11 @@ int detect_sensors_par2addr_init(int port,int sub_chn){
pages = mt9f002_pages;
atab = mt9f002_ahead_tab;
break;
case SENSOR_LEPTON35:
par2addr = lepton_par2addr;
pages = lepton_pages;
atab = lepton_ahead_tab;
break;
}
if (par2addr){
// convert to key-value
......@@ -483,44 +496,6 @@ int detect_sensors_par2addr_init(int port,int sub_chn){
sensorPortConfig[port].ahead_tab[sub_chn] = atab;
}
/*
// all .mux and .sensor are already filled out
for (portx = 0; portx < SENSOR_PORTS; portx++){
// that's from device tree, fpga is not programmed yet
dev_dbg(g_dev_ptr,"port: %d mux: %d sensors: %d %d %d %d\n",
portx,
sensorPortConfig[portx].mux,
sensorPortConfig[portx].sensor[0],
sensorPortConfig[portx].sensor[1],
sensorPortConfig[portx].sensor[2],
sensorPortConfig[portx].sensor[3]
);
// sub_chn = 3 is never used
for (sub_chn = 0; sub_chn < 4; sub_chn++){
//sensorPortConfig[port].sensor[sub_chn];
switch (sensorPortConfig[portx].sensor[sub_chn]) {
case SENSOR_MT9P006:
// get sensor table
par2addr = mt9x001_par2addr;
pages = mt9x001_pages;
break;
case SENSOR_MT9F002:
// get sensor table
par2addr = mt9f002_par2addr;
pages = mt9f002_pages;
break;
}
if (par2addr){
// convert to key-value
par2addr_fill(par2addr,sensorPortConfig[portx].par2addr[sub_chn]);
// save pointer to static LUT
sensorPortConfig[portx].pages_ptr[sub_chn] = pages;
}
}
}
*/
return 0;
}
......
......@@ -45,7 +45,7 @@ struct sensor_port_config_t {
extern struct sensor_port_config_t *pSensorPortConfig;
typedef enum {NONE,PARALLEL12,HISPI4} sens_iface_t; ///< Sensor port interface type
typedef enum {NONE,PARALLEL12,HISPI4,VOSPI} 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);
......
......@@ -294,46 +294,46 @@ static int __init elphelmem_init(void)
pr_err("ERROR allocating Bidirectional DMA memory buffer\n");
}
pr_info("Coherent buffer vaddr: 0x%08X\n",(u32) pElphel_buf -> vaddr);
pr_info("Coherent buffer paddr: 0x%08X\n",(u32) pElphel_buf -> paddr);
pr_info("Coherent buffer length: 0x%08X\n",(u32) pElphel_buf -> size * PAGE_SIZE);
pr_info("Coherent buffer vaddr: 0x%08x\n",(u32) pElphel_buf -> vaddr);
pr_info("Coherent buffer paddr: 0x%08x\n",(u32) pElphel_buf -> paddr);
pr_info("Coherent buffer length: 0x%08lx\n",(u32) pElphel_buf -> size * PAGE_SIZE);
pr_info(" circbuf channel 0 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" circbuf channel 0 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> circbuf_chn0_vaddr,
(u32) pElphel_buf -> circbuf_chn0_paddr,
(u32) pElphel_buf-> circbuf_chn0_size * PAGE_SIZE);
pr_info(" circbuf channel 1 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" circbuf channel 1 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> circbuf_chn1_vaddr,
(u32) pElphel_buf -> circbuf_chn1_paddr,
(u32) pElphel_buf-> circbuf_chn1_size * PAGE_SIZE);
pr_info(" circbuf channel 2 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" circbuf channel 2 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> circbuf_chn2_vaddr,
(u32) pElphel_buf -> circbuf_chn2_paddr,
(u32) pElphel_buf-> circbuf_chn2_size * PAGE_SIZE);
pr_info(" circbuf channel 3 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" circbuf channel 3 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> circbuf_chn3_vaddr,
(u32) pElphel_buf -> circbuf_chn3_paddr,
(u32) pElphel_buf-> circbuf_chn3_size * PAGE_SIZE);
pr_info(" raw channel 0 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" raw channel 0 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> raw_chn0_vaddr,
(u32) pElphel_buf -> raw_chn0_paddr,
(u32) pElphel_buf-> raw_chn0_size * PAGE_SIZE);
pr_info(" raw channel 1 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" raw channel 1 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> raw_chn1_vaddr,
(u32) pElphel_buf -> raw_chn1_paddr,
(u32) pElphel_buf-> raw_chn1_size * PAGE_SIZE);
pr_info(" raw channel 2 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" raw channel 2 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> raw_chn2_vaddr,
(u32) pElphel_buf -> raw_chn2_paddr,
(u32) pElphel_buf-> raw_chn2_size * PAGE_SIZE);
pr_info(" raw channel 3 vaddr: 0x%08X paddr: 0x%08X length 0x%08X\n",
pr_info(" raw channel 3 vaddr: 0x%08x paddr: 0x%08x length 0x%08lx\n",
(u32) pElphel_buf -> raw_chn3_vaddr,
(u32) pElphel_buf -> raw_chn3_paddr,
(u32) pElphel_buf-> raw_chn3_size * PAGE_SIZE);
......
......@@ -75,12 +75,17 @@
static const char * const exif393_devs[]={
DEV393_DEVNAME(DEV393_EXIF_TEMPLATE),
DEV393_DEVNAME(DEV393_TIFF_TEMPLATE),
DEV393_DEVNAME(DEV393_EXIF_METADIR),
DEV393_DEVNAME(DEV393_EXIF_TIME),
DEV393_DEVNAME(DEV393_EXIF0),
DEV393_DEVNAME(DEV393_EXIF1),
DEV393_DEVNAME(DEV393_EXIF2),
DEV393_DEVNAME(DEV393_EXIF3),
DEV393_DEVNAME(DEV393_TIFF0),
DEV393_DEVNAME(DEV393_TIFF1),
DEV393_DEVNAME(DEV393_TIFF2),
DEV393_DEVNAME(DEV393_TIFF3),
DEV393_DEVNAME(DEV393_EXIF_META0),
DEV393_DEVNAME(DEV393_EXIF_META1),
DEV393_DEVNAME(DEV393_EXIF_META2),
......@@ -91,12 +96,17 @@ static const int exif393_major = DEV393_MAJOR(DEV393_EXIF_TEMPLATE);
static const int exif393_minor[]={
DEV393_MINOR(DEV393_EXIF_TEMPLATE),
DEV393_MINOR(DEV393_TIFF_TEMPLATE),
DEV393_MINOR(DEV393_EXIF_METADIR),
DEV393_MINOR(DEV393_EXIF_TIME),
DEV393_MINOR(DEV393_EXIF0),
DEV393_MINOR(DEV393_EXIF1),
DEV393_MINOR(DEV393_EXIF2),
DEV393_MINOR(DEV393_EXIF3),
DEV393_MINOR(DEV393_TIFF0),
DEV393_MINOR(DEV393_TIFF1),
DEV393_MINOR(DEV393_TIFF2),
DEV393_MINOR(DEV393_TIFF3),
DEV393_MINOR(DEV393_EXIF_META0),
DEV393_MINOR(DEV393_EXIF_META1),
DEV393_MINOR(DEV393_EXIF_META2),
......@@ -119,12 +129,16 @@ static int exif_fields = 0; // total number of the Exif fields in the he
static int exif_template_size = 0; // size of Exif template
static char exif_template[MAX_EXIF_SIZE];
//static int tiff_fields = 0; // total number of the Tiff fields in the header
static int tiff_template_size = 0; // size of Tiff template
static char tiff_template[MAX_EXIF_SIZE];
static int aexif_meta_size[SENSOR_PORTS] = {0,0,0,0}; // size of Exif meta data page (is it the same for all ports?) 393: set as individual
static int aexif_wp[SENSOR_PORTS] = {1,1,1,1}; // frame write pointer in the meta_buffer
static int aexif_enabled[SENSOR_PORTS] = {0,0,0,0}; // enable storing of frame meta data, enable reading Exif data
static int aexif_valid[SENSOR_PORTS] = {0,0,0,0}; // Exif tables and buffer are valid.
static char * ameta_buffer[SENSOR_PORTS]= {NULL,NULL,NULL,NULL}; // dynamically allocated buffer to store frame meta data.
static char exif_tmp_buff[MAX_EXIF_SIZE];
static char exif_tmp_buff[MAX_EXIF_SIZE]; // Not thread safe - should be fixed!
//static char * meta_buffer=NULL; // dynamically allocated buffer to store frame meta data.
// page 0 - temporary storage, 1..MAX_EXIF_FRAMES - buffer
......@@ -166,12 +180,21 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi
switch (minor) {
case DEV393_MINOR(DEV393_EXIF_TEMPLATE):
return exif_template_size;
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
return tiff_template_size;
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
sensor_port = minor - DEV393_MINOR(DEV393_EXIF0);
return aexif_enabled[sensor_port]? (exif_template_size * (MAX_EXIF_FRAMES+1)):0;
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
sensor_port = minor - DEV393_MINOR(DEV393_TIFF0);
return aexif_enabled[sensor_port]? (tiff_template_size * (MAX_EXIF_FRAMES+1)):0;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
......@@ -185,15 +208,26 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi
default:return 0;
}
}
ssize_t minor_max_size(int minor) { //return max file size for different minors
switch (minor) {
case DEV393_MINOR(DEV393_EXIF_TEMPLATE):
return MAX_EXIF_SIZE;
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
return MAX_EXIF_SIZE;
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
......@@ -259,6 +293,8 @@ int exif_rebuild_chn(int sensor_port, int frames) {
return 0;
}
int exif_enable(int en) {
int sensor_port,rslt;
for (sensor_port =0; sensor_port < SENSOR_PORTS; sensor_port++){
......@@ -296,8 +332,8 @@ inline void write_meta_raw_irq(int sensor_port, char * data, int offset, int len
inline int write_meta_irq(int sensor_port, char * data, int * indx, unsigned long ltag, int len) { //write data to meta, called from IRQ(len==0 => use field length)
int i;
if (!aexif_enabled[sensor_port]) return 0;
if (indx && (dir_table[* indx].ltag==ltag)) i=*indx;
else {
if (indx && (dir_table[* indx].ltag==ltag)) i=*indx; // cache hit
else { // cache miss
for (i=0; i<exif_fields; i++) if (dir_table[i].ltag==ltag) break;
if (i>=exif_fields) return -1; //ltag not found
}
......@@ -500,11 +536,16 @@ int exif_open(struct inode *inode, struct file *filp) {
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
case DEV393_MINOR(DEV393_EXIF_TEMPLATE):
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
case DEV393_MINOR(DEV393_EXIF_METADIR):
case DEV393_MINOR(DEV393_EXIF_TIME):
break;
......@@ -529,6 +570,11 @@ int exif_release(struct inode *inode, struct file *filp){
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
break;
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
break;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
......@@ -536,6 +582,8 @@ int exif_release(struct inode *inode, struct file *filp){
break;
case DEV393_MINOR(DEV393_EXIF_TEMPLATE):
break;
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
break;
case DEV393_MINOR(DEV393_EXIF_METADIR):
break;
case DEV393_MINOR(DEV393_EXIF_TIME):
......@@ -573,7 +621,8 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
} else {
switch (p) {
case DEV393_MINOR(DEV393_EXIF_TEMPLATE): //enable/disable
case DEV393_MINOR(DEV393_EXIF_TEMPLATE): // enable/disable
// case DEV393_MINOR(DEV393_TIFF_TEMPLATE): // both files offer the same lseek commands
switch (offset) {
case EXIF_LSEEK_DISABLE:
exif_enable(0);
......@@ -599,6 +648,17 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
// file->f_pos=exif_meta_size * offset;
file->f_pos=exif_template_size * offset;
break;
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
// sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
if (offset > MAX_EXIF_FRAMES) return -EOVERFLOW; //larger than buffer
// file->f_pos=exif_meta_size * offset;
file->f_pos=tiff_template_size * offset;
break;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
......@@ -662,7 +722,7 @@ ssize_t exif_write (struct file * file, const char * buf, size_t count, loff
int disabled_err=0;
dev_dbg(g_devfp_ptr,"minor=0x%x\n", p);
if ((*off+count)>maxsize) {
if ((*off+count) > maxsize) {
// dev_warn(g_devfp_ptr,"%s:%d: Data (0x%x) does not fit into 0x%x bytes\n",__FILE__,__LINE__, (int) (*off+count), maxsize);
dev_dbg(g_devfp_ptr,"Data (0x%x) does not fit into 0x%x bytes, minor = 0x%x\n",(int) (*off+count), maxsize, p);
return -EOVERFLOW;
......@@ -673,6 +733,11 @@ ssize_t exif_write (struct file * file, const char * buf, size_t count, loff
if (copy_from_user(&exif_template[*off], buf, count)) return -EFAULT;
exif_template_size=*off+count;
break;
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
exif_invalidate();
if (copy_from_user(&tiff_template[*off], buf, count)) return -EFAULT;
tiff_template_size=*off+count;
break;
case DEV393_MINOR(DEV393_EXIF_METADIR):
exif_invalidate();
cp= (char *) &dir_table;
......@@ -716,6 +781,12 @@ ssize_t exif_write (struct file * file, const char * buf, size_t count, loff
case DEV393_MINOR(DEV393_EXIF3):
return -EINVAL; // no writing - read only
break;
case DEV393_MINOR(DEV393_TIFF0):
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
return -EINVAL; // no writing - read only
break;
default:return -EINVAL;
}
*off+=count;
......@@ -733,6 +804,8 @@ ssize_t exif_read (struct file * file, char * buf, size_t count, loff_t *of
int start_p, page_p,i;
int sensor_port;
char tmp[MAX_EXIF_SIZE]; //! Or is it possible to disable IRQ while copy_from_user()?
int is_tiff = 0;
int template_size;
/*
Does not work with PHP - always read 8192 bytes
if ((*off+count)>maxsize) {
......@@ -751,6 +824,9 @@ ssize_t exif_read (struct file * file, char * buf, size_t count, loff_t *of
case DEV393_MINOR(DEV393_EXIF_TEMPLATE):
if (copy_to_user(buf, &exif_template[*off], count)) return -EFAULT;
break;
case DEV393_MINOR(DEV393_TIFF_TEMPLATE):
if (copy_to_user(buf, &tiff_template[*off], count)) return -EFAULT;
break;
case DEV393_MINOR(DEV393_EXIF_METADIR):
cp= (char *) &dir_table;
if (copy_to_user(buf, &cp[*off], count)) return -EFAULT;
......@@ -767,26 +843,42 @@ ssize_t exif_read (struct file * file, char * buf, size_t count, loff_t *of
if (!aexif_enabled[sensor_port]) return 0;
if (copy_to_user(buf, &ameta_buffer[sensor_port][*off], count)) return -EFAULT;
break;
case DEV393_MINOR(DEV393_TIFF0):// generates exif data by merging exif_template with the selected meta_buffer page
case DEV393_MINOR(DEV393_TIFF1):
case DEV393_MINOR(DEV393_TIFF2):
case DEV393_MINOR(DEV393_TIFF3):
is_tiff=1;
/* no break */
case DEV393_MINOR(DEV393_EXIF0):// generates exif data by merging exif_template with the selected meta_buffer page
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
sensor_port = (p - (is_tiff ? DEV393_MINOR(DEV393_TIFF0):DEV393_MINOR(DEV393_EXIF0))) & 3; // &3 just to make compiler happy
//will truncate by the end of current page
if (!aexif_enabled[sensor_port]) return 0;
i=((int) *off) / exif_template_size;
dev_dbg(g_devfp_ptr,"count= 0x%x, *off= 0x%x, i=0x%x, exif_template_size=0x%x\n", (int) count, (int) *off, (int) i, (int) exif_template_size);
//arch/cris/arch-v32/drivers/elphel/exif353.c:590:count= 0x2000, *off= 0x410, i=0x82, exif_template_size=0x208
start_p=i*exif_template_size;
template_size = is_tiff ? tiff_template_size: exif_template_size;
i=((int) *off) / template_size;
dev_dbg(g_devfp_ptr,"count= 0x%x, *off= 0x%x, i=0x%x, template_size=0x%x\n", (int) count, (int) *off, (int) i, (int) template_size);
//arch/cris/arch-v32/drivers/elphel/exif353.c:590:count= 0x2000, *off= 0x410, i=0x82, template_size=0x208
start_p=i*template_size;
page_p= *off - start_p;
dev_dbg(g_devfp_ptr,"count= 0x%x, pos= 0x%x, start_p=0x%x, page_p=0x%x, i=0x%x, exif_template_size=0x%x\n", (int) count, (int) *off, (int)start_p, (int)page_p,(int) i, (int) exif_template_size);
//arch/cris/arch-v32/drivers/elphel/exif353.c:591:count= 0x2000, pos= 0x410, start_p=0x10810, page_p=0xfffefc00, i=0x82, exif_template_size=0x208
dev_dbg(g_devfp_ptr,"count= 0x%x, pos= 0x%x, start_p=0x%x, page_p=0x%x, i=0x%x, template_size=0x%x\n", (int) count, (int) *off, (int)start_p, (int)page_p,(int) i, (int) template_size);
//arch/cris/arch-v32/drivers/elphel/exif353.c:591:count= 0x2000, pos= 0x410, start_p=0x10810, page_p=0xfffefc00, i=0x82, template_size=0x208
metap= &ameta_buffer[sensor_port][i*aexif_meta_size[sensor_port]]; // pointer to the start of the selected page in frame meta_buffer
if ((page_p+count) > exif_template_size) count=exif_template_size-page_p;
memcpy(tmp,exif_template, exif_template_size);
dev_dbg(g_devfp_ptr,"count= 0x%x, pos= 0x%x, start_p=0x%x, page_p=0x%x\n", (int) count, (int) *off, (int)start_p, (int)page_p);
for (i=0;i<exif_fields;i++){
memcpy(&tmp[dir_table[i].dst],&metap[dir_table[i].src], dir_table[i].len);
if ((page_p+count) > template_size) count=template_size-page_p;
// memcpy(tmp,exif_template, template_size);
// dev_dbg(g_devfp_ptr,"count= 0x%x, pos= 0x%x, start_p=0x%x, page_p=0x%x\n", (int) count, (int) *off, (int)start_p, (int)page_p);
if (is_tiff) {
memcpy(tmp,tiff_template, template_size);
for (i=0;i<exif_fields;i++) {
if (dir_table[i].dst_tiff > 0) memcpy(&tmp[dir_table[i].dst_tiff],&metap[dir_table[i].src], dir_table[i].len);
}
} else {
memcpy(tmp,exif_template, template_size);
for (i=0;i<exif_fields;i++) {
if (dir_table[i].dst_exif > 0) memcpy(&tmp[dir_table[i].dst_exif],&metap[dir_table[i].src], dir_table[i].len);
}
}
if (copy_to_user(buf, &tmp[page_p], count)) return -EFAULT;
break;
......@@ -797,7 +889,11 @@ ssize_t exif_read (struct file * file, char * buf, size_t count, loff_t *of
return count;
}
/* This code is copied from exif_read, consider replacing it with this function invocation */
/* This code is copied from exif_read, consider replacing it with this function invocation
* It is used only in ahci_elphel.c for raw write, currently will use only Jpeg/Exif,(no Tiff) */
// Need to get rid of static buffer
size_t exif_get_data(int sensor_port, unsigned short meta_index, void *buff, size_t buff_sz)
{
size_t count = exif_template_size;
......@@ -819,12 +915,12 @@ size_t exif_get_data(int sensor_port, unsigned short meta_index, void *buff, siz
memcpy(exif_tmp_buff, exif_template, exif_template_size);
D(printk("%s: count= 0x%x, pos= 0x%x, start_p=0x%x, page_p=0x%x\n", __func__, (int) count, (int) off, (int)start_p, (int)page_p));
for (i = 0; i < exif_fields; i++) {
memcpy(&exif_tmp_buff[dir_table[i].dst], &metap[dir_table[i].src], dir_table[i].len);
if (dir_table[i].dst_exif > 0) memcpy(&exif_tmp_buff[dir_table[i].dst_exif], &metap[dir_table[i].src], dir_table[i].len);
}
memcpy(buff, &exif_tmp_buff[page_p], count);
return count;
}
EXPORT_SYMBOL_GPL(exif_get_data);
EXPORT_SYMBOL_GPL(exif_get_data); // @suppress("Unused function declaration") as it is still needed
//!++++++++++++++++++++++++++++++++++++ _init() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -876,8 +972,8 @@ static void __exit exif_exit(void)
dev_dbg(NULL, "unregistering driver");
}
module_exit(exif_exit);
module_init(exif_init);
module_exit(exif_exit); // @suppress("Unused variable declaration in file scope")
module_init(exif_init); // @suppress("Unused variable declaration in file scope")
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
......
......@@ -1499,6 +1499,8 @@ int setFramePars(int sensor_port, ///< sensor port number (0
unsigned long *funcs2call =afuncs2call[sensor_port];
dev_dbg(g_devfp_ptr, "port= %d, this_framepars=0x%x numPars=%d\n", sensor_port, (int)this_framepars, numPars);
// dev_info(g_devfp_ptr, "port= %d, this_framepars=0x%x numPars=%d\n", sensor_port, (int)this_framepars, numPars);
MDP(DBGB_FSFP,sensor_port,"this_framepars=0x%x numPars=%d\n", (int)this_framepars, numPars)
for (npar = 0; npar < numPars; npar++) {
......@@ -1506,6 +1508,9 @@ int setFramePars(int sensor_port, ///< sensor port number (0
val = pars[npar].val;
index = pars[npar].num & 0xffff;
dev_dbg(g_devfp_ptr, ": --- frame16=%d index=%d (0x%x) val=0x%x, findex_future = 0x%x\n", frame16, index, (int)pars[npar].num, (int)val, findex_future);
// dev_info(g_devfp_ptr, ": --- frame16=%d index=%d (0x%x) val=0x%x, findex_future = 0x%x\n", frame16, index, (int)pars[npar].num, (int)val, findex_future);
MDP(DBGB_FSFV,sensor_port," --- frame16=%d index=%d (0x%x) val=0x%x\n", frame16, index, (int)pars[npar].num, (int)val)
// remark: code below looks similar to setFramePar function, call it instead
if (index > ((index >= FRAMEPAR_GLOBALS) ? (P_MAX_GPAR + FRAMEPAR_GLOBALS) : P_MAX_PAR)) {
......@@ -2028,12 +2033,14 @@ static ssize_t show_fpga_sensor_interface(struct device *dev, struct device_attr
if (!hardware_initialized)
return -EBUSY;
switch (x393_sensor_interface()){
case 0:
case FPGA_PAR12:
return sprintf(buf,"PAR12\n");
case 1:
case FPGA_HISPI:
return sprintf(buf,"HISPI\n");
case FPGA_VOSPI:
return sprintf(buf,"VOSPI\n");
default:
return sprintf(buf,"0x%08%lx\n", x393_sensor_interface());
return sprintf(buf,"0x%08x\n", (int) x393_sensor_interface());
}
}
......
......@@ -115,7 +115,6 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h>
......
......@@ -17,9 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*-----------------------------------------------------------------------------**
*! $Log: imu_log353.c,v $
*! Revision 1.5 2012/04/14 03:53:48 elphel
*! bug fix in the driver (was producing errors in 3-4 hours)
*! $Log: imu_log353.c,v $
*! Revision 1.5 2012/04/14 03:53:48 elphel
*! bug fix in the driver (was producing errors in 3-4 hours)
*!
*! Revision 1.3 2011/08/13 00:54:08 elphel
*! added /dev/imu_ctl where it is possible to read current logger settings
......@@ -47,8 +47,6 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <asm/delay.h>
#include <asm/uaccess.h> // copy_*_user
#include <uapi/elphel/c313a.h>
......
......@@ -27,7 +27,7 @@
#include <linux/fs.h>
#include <asm/uaccess.h> // copy_*_user
#include <linux/of.h> // Device Tree
#include <linux/uaccess.h>
#include <uapi/elphel/c313a.h> // PARS_FRAMES_MASK
......
......@@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
//#include <linux/platform_device.h>
......@@ -64,61 +65,61 @@ LUT to map SENSOR_REGSxxx to internal sensor register addresses
* (for MT9X001 it's a 1-to-1 mapping)
*/
const unsigned short mt9f002_par2addr[] = {
P_MT9F002_MODEL_ID, P_REG_MT9F002_MODEL_ID,
P_MT9F002_RESET, P_REG_MT9F002_RESET_REGISTER,
P_MT9F002_EXPOS, P_REG_MT9F002_COARSE_INTEGRATION_TIME,
P_MT9F002_TEST_PATTERN, P_REG_MT9F002_TEST_PATTERN_MODE,
P_MT9F002_GAIN, P_REG_MT9F002_GLOBAL_GAIN,
P_MT9F002_GAINGR, P_REG_MT9F002_GREEN1_GAIN,
P_MT9F002_GAINR, P_REG_MT9F002_RED_GAIN,
P_MT9F002_GAINB, P_REG_MT9F002_BLUE_GAIN,
P_MT9F002_GAINGB, P_REG_MT9F002_GREEN2_GAIN,
P_MT9F002_HISPI_TIMING, P_REG_MT9F002_HISPI_TIMING,
P_MT9F002_SMIA_PLL_MULTIPLIER, P_REG_MT9F002_SMIA_PLL_MULTIPLIER,
P_MT9F002_HISPI_CONTROL_STATUS, P_REG_MT9F002_HISPI_CONTROL_STATUS,
P_MT9F002_DATAPATH_SELECT, P_REG_MT9F002_DATAPATH_SELECT,
P_MT9F002_RESET_REGISTER, P_REG_MT9F002_RESET_REGISTER,
P_MT9F002_COARSE_INTEGRATION_TIME, P_REG_MT9F002_COARSE_INTEGRATION_TIME,
P_MT9F002_FINE_INTEGRATION_TIME, P_REG_MT9F002_FINE_INTEGRATION_TIME,
P_MT9F002_Y_ADDR_START, P_REG_MT9F002_Y_ADDR_START,
P_MT9F002_Y_ADDR_END, P_REG_MT9F002_Y_ADDR_END,
P_MT9F002_X_ADDR_START, P_REG_MT9F002_X_ADDR_START,
P_MT9F002_X_ADDR_END, P_REG_MT9F002_X_ADDR_END,
P_MT9F002_Y_OUTPUT_SIZE, P_REG_MT9F002_SMIA_Y_OUTPUT_SIZE,
P_MT9F002_X_OUTPUT_SIZE, P_REG_MT9F002_SMIA_X_OUTPUT_SIZE,
P_MT9F002_LINE_LENGTH_PCK, P_REG_MT9F002_LINE_LENGTH_PCK,
P_MT9F002_MODEL_ID, P_REG_MT9F002_MODEL_ID,
P_MT9F002_RESET, P_REG_MT9F002_RESET_REGISTER,
P_MT9F002_EXPOS, P_REG_MT9F002_COARSE_INTEGRATION_TIME,
P_MT9F002_TEST_PATTERN, P_REG_MT9F002_TEST_PATTERN_MODE,
P_MT9F002_GAIN, P_REG_MT9F002_GLOBAL_GAIN,
P_MT9F002_GAINGR, P_REG_MT9F002_GREEN1_GAIN,
P_MT9F002_GAINR, P_REG_MT9F002_RED_GAIN,
P_MT9F002_GAINB, P_REG_MT9F002_BLUE_GAIN,
P_MT9F002_GAINGB, P_REG_MT9F002_GREEN2_GAIN,
P_MT9F002_HISPI_TIMING, P_REG_MT9F002_HISPI_TIMING,
P_MT9F002_SMIA_PLL_MULTIPLIER, P_REG_MT9F002_SMIA_PLL_MULTIPLIER,
P_MT9F002_HISPI_CONTROL_STATUS, P_REG_MT9F002_HISPI_CONTROL_STATUS,
P_MT9F002_DATAPATH_SELECT, P_REG_MT9F002_DATAPATH_SELECT,
P_MT9F002_RESET_REGISTER, P_REG_MT9F002_RESET_REGISTER,
P_MT9F002_COARSE_INTEGRATION_TIME, P_REG_MT9F002_COARSE_INTEGRATION_TIME,
P_MT9F002_FINE_INTEGRATION_TIME, P_REG_MT9F002_FINE_INTEGRATION_TIME,
P_MT9F002_Y_ADDR_START, P_REG_MT9F002_Y_ADDR_START,
P_MT9F002_Y_ADDR_END, P_REG_MT9F002_Y_ADDR_END,
P_MT9F002_X_ADDR_START, P_REG_MT9F002_X_ADDR_START,
P_MT9F002_X_ADDR_END, P_REG_MT9F002_X_ADDR_END,
P_MT9F002_Y_OUTPUT_SIZE, P_REG_MT9F002_SMIA_Y_OUTPUT_SIZE,
P_MT9F002_X_OUTPUT_SIZE, P_REG_MT9F002_SMIA_X_OUTPUT_SIZE,
P_MT9F002_LINE_LENGTH_PCK, P_REG_MT9F002_LINE_LENGTH_PCK,
P_MT9F002_X_ODD_INC, P_REG_MT9F002_SMIA_X_ODD_INC,
P_MT9F002_MIN_LINE_BLANKING_PCK, P_REG_MT9F002_SMIA_MIN_LINE_BLANKING_PCK,
P_MT9F002_MIN_LINE_LENGTH_PCK, P_REG_MT9F002_SMIA_MIN_LINE_LENGTH_PCK,
P_MT9F002_FRAME_LENGTH_LINES, P_REG_MT9F002_FRAME_LENGTH_LINES,
P_MT9F002_MIN_FRAME_BLANKING_LINES, P_REG_MT9F002_SMIA_MIN_FRAME_BLANKING_LINES,
P_MT9F002_READ_MODE, P_REG_MT9F002_READ_MODE,
P_MT9F002_SLAVE_MODE, P_REG_MT9F002_SLAVE_MODE,
0xffff // END indicator
P_MT9F002_FRAME_LENGTH_LINES, P_REG_MT9F002_FRAME_LENGTH_LINES,
P_MT9F002_MIN_FRAME_BLANKING_LINES, P_REG_MT9F002_SMIA_MIN_FRAME_BLANKING_LINES,
P_MT9F002_READ_MODE, P_REG_MT9F002_READ_MODE,
P_MT9F002_SLAVE_MODE, P_REG_MT9F002_SLAVE_MODE,
0xffff // END indicator
};
/**
* get at least one parameter for a page
*/
const unsigned short mt9f002_pages[] = {
P_REG_MT9F002_SMIA_MODEL_ID, // page 0x00
P_REG_MT9F002_SMIA_MODE_SELECT, // page 0x01
P_REG_MT9F002_SMIA_FINE_INTEGRATION_TIME, // page 0x02
P_REG_MT9F002_SMIA_VT_PIX_CLK_DIV, // page 0x03
P_REG_MT9F002_SMIA_SCALING_MODE, // page 0x04
P_REG_MT9F002_SMIA_COMPRESSION_MODE, // page 0x05
P_REG_MT9F002_SMIA_TEST_PATTERN_MODE, // page 0x06
P_REG_MT9F002_SMIA_INTEGRATION_TIME_CAPABILITY, // page 0x10
P_REG_MT9F002_SMIA_MIN_EXT_CLK_FREQ_MHZ, // page 0x11
P_REG_MT9F002_SMIA_SCALING_CAPABILITY, // page 0x12
P_REG_MT9F002_SMIA_COMPRESSION_CAPABILITY, // page 0x13
P_REG_MT9F002_SMIA_MATRIX_ELEMENT_REDINRED, // page 0x14
P_REG_MT9F002_MODEL_ID, // page 0x30
P_REG_MT9F002_OTPM_CFG, // page 0x31
P_REG_MT9F002_P_GR_P0Q0, // page 0x36
P_REG_MT9F002_P_GR_P4Q0, // page 0x37
P_REG_MT9F002_DAC_LD_FBIAS, // page 0x3E
0xffff // END indicator
P_REG_MT9F002_SMIA_MODEL_ID, // page 0x00
P_REG_MT9F002_SMIA_MODE_SELECT, // page 0x01
P_REG_MT9F002_SMIA_FINE_INTEGRATION_TIME, // page 0x02
P_REG_MT9F002_SMIA_VT_PIX_CLK_DIV, // page 0x03
P_REG_MT9F002_SMIA_SCALING_MODE, // page 0x04
P_REG_MT9F002_SMIA_COMPRESSION_MODE, // page 0x05
P_REG_MT9F002_SMIA_TEST_PATTERN_MODE, // page 0x06
P_REG_MT9F002_SMIA_INTEGRATION_TIME_CAPABILITY, // page 0x10
P_REG_MT9F002_SMIA_MIN_EXT_CLK_FREQ_MHZ, // page 0x11
P_REG_MT9F002_SMIA_SCALING_CAPABILITY, // page 0x12
P_REG_MT9F002_SMIA_COMPRESSION_CAPABILITY, // page 0x13
P_REG_MT9F002_SMIA_MATRIX_ELEMENT_REDINRED, // page 0x14
P_REG_MT9F002_MODEL_ID, // page 0x30
P_REG_MT9F002_OTPM_CFG, // page 0x31
P_REG_MT9F002_P_GR_P0Q0, // page 0x36
P_REG_MT9F002_P_GR_P4Q0, // page 0x37
P_REG_MT9F002_DAC_LD_FBIAS, // page 0x3E
0xffff // END indicator
};
/**
......@@ -139,7 +140,7 @@ const unsigned short mt9f002_ahead_tab[] =
onchange_i2c, 0, 0, 0, 0, 0, 0, /// program i2c
onchange_initsensor, 1, 0, 0, 0, 0, 0, /// resets sensor, reads sensor registers, schedules "secret" manufacturer's corrections to the registers (stops/re-enables hardware i2c)
onchange_afterinit, 0, 0, 0, 0, 0, 0, /// restore image size, decimation,... after sensor reset or set them according to sensor capabilities if none were specified
onchange_multisens, 0, 2, 1, 1, 1, 0, /// chnages related to multiplexed sensors
onchange_multisens, 0, 2, 1, 1, 1, 0, /// changes related to multiplexed sensors
onchange_window, 0, 2, 1, 2, 1, 0, /// program sensor WOI and mirroring (flipping) - NOTE: 1 bad frame to skip
onchange_window_safe, 0, 1, 1, 1, 1, 0, /// program sensor WOI and mirroring (flipping) - NOTE: no bad frames
onchange_exposure, 0, 2, 1, 2, 1, 0, /// program exposure
......@@ -280,6 +281,8 @@ int mt9f002_pgm_gains (int sensor_port, struct sensor_t * sensor, struct
int mt9f002_pgm_triggermode (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9f002_pgm_sensorregs (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int mt9f002_phases_adjust_port(int sensor_port);
/**
* Detect and initialize sensor and related data structures
*/
......@@ -292,6 +295,13 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
///< @return 0 - OK, negative - error
{
int i,n;
int regaddr,regval,regnum;
int nupdate=0;
int colamp_gain, a2_gain, gain, a2_inc;
u32 i2c_read_data_dw[256];
int color;
struct frameparspair_t pars_to_update[262+(MAX_SENSORS * P_MULTI_NUMREGS )]; // for all the sensor registers. Other P_* values will reuse the same ones
u32 i2c_read_dataw;
......@@ -331,8 +341,11 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
psensor->i2c_addr = dc->slave7;
}
// don't need to disable and enable SOF since phase adjustment has been moved here
/*
dis_sof.dis_sof = 1;
x393_sens_sync_mult(dis_sof,sensor_port);
*/
// set control lines
sensio_ctl.mrst = 1;
......@@ -352,6 +365,31 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
// delay until sensor gets responsive to i2c commands
// 100us - was not enough
/* See MT9F002_DS_B.pdf p.35: Power-On Reset Sequence (and Soft Reset Sequence?):
*
* When power is applied - the sensor enters a low-power standby. Exit from which is
* controlled by the later of 2 events:
* - negation of the RESET_BAR
* - a timeout of the internal power-on reset circuit
*
* There's no need to assert/deassert RESET_BAR but we hold it asserted then deassert.
*
* The sensor is supposed to leave the hardware standby state and perform some initialization
* sequence that takes T_is = 2700 EXTCLK (MT9F002_EXT_CLK):
* - for 1.6MHz T_is = 1.6 ms
* - for 24.444MHz T_is = 110 us
*
* While doing initialization sensor is unresponsive to i2c.
*
* After init it enters a low-power software standby and enables Voltage-Controlled Oscillator (VCO).
* And internal delay will keep PLL disconneced for up to 1ms so that PLL can lock.
* VCO lock time is 200 us (typical) - 1000 us (max)
*
* Soft Reset via R0x0103 is pretty much the same as Power-on reset.
*
* So:
*/
udelay(200);
X3X3_I2C_RCV2(sensor_port, psensor->i2c_addr, P_REG_MT9F002_MODEL_ID, &i2c_read_dataw);
......@@ -381,8 +419,6 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
add_sensor_proc(sensor_port,onchange_triggermode, &mt9f002_pgm_triggermode); // program sensor trigger mode
add_sensor_proc(sensor_port,onchange_sensorregs, &mt9f002_pgm_sensorregs); // write sensor registers (only changed from outside the driver as they may have different latencies)?
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); // should cause other actions
common_pars->sensors[sensor_port] = sensor->sensorType;
// setFramePar(thispars, P_SENSOR | FRAMEPAIR_FORCE_NEWPROC, sensor->sensorType); // force actions
// MDD1(dev_dbg(g_dev_ptr,"\n"));
......@@ -399,6 +435,103 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
sensio_ctl.gp1 = 0x3; // inverted iaro - 'active high'
x393_sensio_ctrl(sensio_ctl,sensor_port);
// The code below was moved from mt9f002_pgm_detectsensor
// BEGIN:
// Init values including PLL multiplier and other default
n = sizeof(mt9f002_inits)/4; // 4 bytes per pair
for(i=0;i<n;i++){
// sa7 is not used
// use broadcast address - which should be 0 for a single sensor?
X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,mt9f002_inits[2*i],mt9f002_inits[2*i+1]);
}
// soft reset
// sa7 is not used
X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,P_REG_MT9F002_RESET_REGISTER,MT9F002_RESET_REGISTER_VALUE);
// delay is not needed, however if bit[0]=1 then it is needed
//udelay(100);
// sensor is supposed to be streaming by now
mt9f002_phases_adjust_port(sensor_port);
// used for debugging
//mdelay(30);
// init register shadows here
// regaddr will be 0xffffffff for not used par
for (i=0; i<256; i++) { // read all registers, one at a time (slower than in 353)
regaddr = pSensorPortConfig[sensor_port].par2addr[0][i];
if (!(regaddr&0xffff0000)){
// TODO: get rid of i2c_addr
X3X3_I2C_RCV2(sensor_port, sensor->i2c_addr, regaddr, &i2c_read_data_dw[i]);
}else{
i2c_read_data_dw[i] = 0;
}
}
dev_dbg(g_dev_ptr,"Read 256 registers (port=%d) ID=0x%x:\n",sensor_port,i2c_read_data_dw[0]);
for (i=0; i<256; i++) { // possible to modify register range to save (that is why nupdate is separate from i)
regval=i2c_read_data_dw[i];
regnum=P_SENSOR_REGS+i;
SETFRAMEPARS_SET(regnum,regval);
}
for (i=0;i<256;i++) {
sensor_reg_copy[sensor_port][i] = i2c_read_data_dw[i];
}
// in mt9x00x there's setFrameParsStatic-call ?!!! Parameters that never change?
if (nupdate) setFrameParsStatic(sensor_port,nupdate,pars_to_update); // save changes to sensor register shadows for all frames
//if (nupdate) setFramePars(sensor_port,thispars,nupdate,pars_to_update); // save changes to sensor register shadows
// next are global pars?
// set gains ranges
SETFRAMEPARS_SET(P_GAIN_MIN, (sensor->minGain256)<<8); // less than that may not saturate sensor and confuse autoexposure/white balancing
SETFRAMEPARS_SET(P_GAIN_MAX, (sensor->maxGain256)<<8);
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
// G_* parameters - can write directly
// fill out the gain tables
for (color=0;color<4;color++){
// 175 =
// 48 (for colamp=1) +
// 48 (for colamp=2) +
// 79 (for colamp=3)
colamp_gain = 2;
a2_gain = 0x30;
a2_inc = 0;
for (i=0;i<176;i++) {
// for mt9x00x
//GLOBALPARS(sensor_port, G_SENSOR_CALIB+(color<<8)+i)= (i>32)? ((i-16)<<14) : (i<<13); // one extra
// for mt9f002
if ((i==48)||(i==96)){
colamp_gain *= 2;
a2_inc = 0;
}
// actual formula
//gain = ((colamp_gain*(a2_gain+a2_inc))<<16)/64;
gain = (colamp_gain*(a2_gain+a2_inc))<<10;
GLOBALPARS(sensor_port, G_SENSOR_CALIB+(color<<8)+i)= gain; // one extra
a2_inc += 1;
}
}
// don't need to disable and enable SOF since phase adjustment has been moved here
// restore SOF (disabled in mt9f002_pgm_detectsensor)
/*
dis_sof.dis_sof = 0;
x393_sens_sync_mult(dis_sof,sensor_port);
*/
// END
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); // should cause other actions
return sensor->sensorType;
//NOTE 353: hardware i2c is turned off (not needed in 393)
}
......@@ -407,7 +540,7 @@ int mt9f002_pgm_detectsensor (int sensor_port, ///< sensor port
// write to sensor's i2c register, test read
int mt9f002_phases_program_phase(int sensor_port, int phase){
int read_phase = 0;
int read_phase = 0xdead;
struct sensor_port_config_t *pcfg;
const char *name;
......@@ -582,6 +715,8 @@ int mt9f002_phases_adjust_port(int sensor_port){
// 4 data lanes - prior knowledge
for(i=0;i<4;i++){
// this was for debugging
//mdelay(10);
phase = mt9f002_phases_adjust_lane(sensor_port,phase,i);
}
......@@ -624,16 +759,25 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port
u32 i2c_read_data_dw[256];
//dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
// sensor is silent before init - this check is redundant
//if (frame16 >= 0) return -1; // should be ASAP
if (!init_done[sensor_port]){
init_done[sensor_port] = true;
}else{
dev_dbg(g_dev_ptr,"{%d} Was going to try to init sensor twice. Exiting\n",sensor_port);
dev_dbg(g_dev_ptr,"{%d} Already initialized. Exit.",sensor_port);
return 0;
}
/* Moved to mt9f002_pgm_detectsensor
* The procedure was supposedly interfered by other functions
* executed on P_SENSOR change
*/
/*
// Init values including PLL multiplier and other default
n = sizeof(mt9f002_inits)/4; // 4 bytes per pair
for(i=0;i<n;i++){
// sa7 is not used
......@@ -650,9 +794,7 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port
// sensor is supposed to be streaming by now
mt9f002_phases_adjust_port(sensor_port);
// restore SOF (disabled in mt9f002_pgm_detectsensor)
dis_sof.dis_sof = 0;
x393_sens_sync_mult(dis_sof,sensor_port);
mdelay(30);
// init register shadows here
// regaddr will be 0xffffffff for not used par
......@@ -665,10 +807,11 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port
i2c_read_data_dw[i] = 0;
}
}
dev_dbg(g_dev_ptr,"Read 256 registers (port=%d) ID=0x%x:\n",sensor_port,i2c_read_data_dw[0]);
for (i=0; i<256; i++) { // possible to modify register range to save (that is why nupdate is separate from i)
regval=i2c_read_data_dw[i];
regval=i2c_read_data_dw[i];
regnum=P_SENSOR_REGS+i;
SETFRAMEPARS_SET(regnum,regval);
}
......@@ -716,6 +859,11 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port
}
}
// restore SOF (disabled in mt9f002_pgm_detectsensor)
dis_sof.dis_sof = 0;
x393_sens_sync_mult(dis_sof,sensor_port);
*/
return 0;
}
......@@ -857,10 +1005,19 @@ int mt9f002_pgm_window_common (int sensor_port, ///< sensor port
//pr_info("mt9f002_pgm_window_common: %d\n",thispars->pars[P_EXPOS]);
/*
dh= thispars->pars[P_DCM_HOR];
dv= thispars->pars[P_DCM_VERT];
bh= thispars->pars[P_BIN_HOR];
bv= thispars->pars[P_BIN_VERT];
*/
/* avoid division by 0 */
dh = thispars->pars[P_DCM_HOR]?thispars->pars[P_DCM_HOR]:1;
dv = thispars->pars[P_DCM_VERT]?thispars->pars[P_DCM_VERT]:1;
bh = thispars->pars[P_BIN_HOR]?thispars->pars[P_BIN_HOR]:1;
bv = thispars->pars[P_BIN_VERT]?thispars->pars[P_BIN_VERT]:1;
//wws = sensor->clearLeft;
ww = thispars->pars[P_SENSOR_PIXH] * dh;
//wwe = ww + wws - 1;
......@@ -868,6 +1025,8 @@ int mt9f002_pgm_window_common (int sensor_port, ///< sensor port
wh = thispars->pars[P_SENSOR_PIXV] * dv;
//whe = whs + wh + MT9F002_VACT_DELAY * dv - 1;
dev_dbg(g_dev_ptr,"{%d} CHECK1 P_SENSOR_PIXH = 0x%04x P_SENSOR_PIXV = 0x%04x\n",sensor_port,ww,wh);
// assuming same for horizontal(H) and vertical(V), margins are from both sides
compressor_margin = (thispars->pars[P_SENSOR_PIXH] - thispars->pars[P_WOI_WIDTH]) >> 1;
//pr_info("Compressor margin = %d\n",compressor_margin);
......@@ -896,6 +1055,8 @@ int mt9f002_pgm_window_common (int sensor_port, ///< sensor port
//whe = whs + wh + MT9F002_VACT_DELAY * dv - 1;
}
dev_dbg(g_dev_ptr,"{%d} CHECK2 P_SENSOR_PIXH = 0x%04x P_SENSOR_PIXV = 0x%04x\n",sensor_port,ww,wh);
// Margins
wl = thispars->pars[P_WOI_LEFT] - compressor_margin;
wt = thispars->pars[P_WOI_TOP] - compressor_margin;
......
......@@ -23,7 +23,7 @@
// bit 9 should have set masking for broken frames
// cleared bit 3 allows writing to some RO registers
//#define MT9F002_RESET_REGISTER_VALUE 0x001c
#define MT9F002_RESET_REGISTER_VALUE 0x0011c
#define MT9F002_RESET_REGISTER_VALUE 0x011c
//#define MT9F002_RESET_REGISTER_VALUE 0x0014
// number of lines to sacrifice before generating Frame Valid
#define MT9F002_VACT_DELAY 2
......
......@@ -1004,6 +1004,9 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
if (frame16 >= 0) return -1; // should be ASAP
// reset sensor by applying MRST (low):
// CCAM_MRST_ON;
//FIXME: No master reset here? Should it be here regardless of debug? ****
if (debug_delays & 0xff) {
dev_dbg(g_dev_ptr,"Resetting MT9X001 sensor, port=%d\n",sensor_port);
sensio_ctl.mrst = 0;
......
......@@ -1354,14 +1354,14 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
// int old_sensor=prev_selected-1; // may be <0
// int new_sensor=selected-1; // >=0
if (multi_unitialized[sensor_port] && (!prev_composite) && (old_sensor>=0)) { // was single-sensor mode, copy P_WOI_* to individual sensor WOI and FLIPS
dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized, old_sensor, multi_fliph,multi_flipv);
dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized[old_sensor], old_sensor, multi_fliph,multi_flipv);
wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_WIDTH];
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_HEIGHT];
wois[(P_MULTI_LEFT1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_LEFT];
wois[(P_MULTI_TOP1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_TOP];
multi_fliph= (multi_fliph & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPH] & 1) << old_sensor);
multi_flipv= (multi_flipv & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPV] & 1) << old_sensor);
dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized, old_sensor, multi_fliph,multi_flipv);
dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized[old_sensor], old_sensor, multi_fliph,multi_flipv);
}
if (multi_unitialized[sensor_port] && (!composite) && (prev_composite || ((new_sensor>=0) && (old_sensor!=new_sensor)))) { // now single-sensor mode, set P_WOI* from saved parameters
if ((wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+new_sensor]==0) || (wois[(P_MULTI_HEIGHT1- P_MULTI_WOI)+new_sensor]==0)) {
......@@ -2181,9 +2181,11 @@ int multisensor_memphase_debug (int sensor_port, ///< Sesnor port number (0..3)
#endif
}
for (i=0; i<8;i++) printk (" %02x ",i); printk("\n");
for (i=0; i<8;i++) printk (" %02x ",i);
printk("\n");
for (n=0;n<64;n+=8) {
for (i=0; i<8;i++) printk ("%04lx ", data[n+i]); printk("\n");
for (i=0; i<8;i++) printk ("%04lx ", data[n+i]);
printk("\n");
}
for (i=0;i<8;i++) setbits[i]=0;
for (n=0;n<64;n++) {
......@@ -2198,7 +2200,8 @@ int multisensor_memphase_debug (int sensor_port, ///< Sesnor port number (0..3)
}
}
OK=(setbits[0]==0) && (setbits[1]==0) && (setbits[2]==0) && (setbits[3]==0x80) && (setbits[4]==0x80) && (setbits[5]==0x80) && (setbits[6]==0) && (setbits[7]==0);
for (i=0; i<8;i++) printk (" %03x ",setbits[i]); printk("\n");
for (i=0; i<8;i++) printk (" %03x ",setbits[i]);
printk("\n");
n=(0x10000*sx)/s;
printk ("Centroid - 0x%x, sx=0x%x, s=0x%x. OK=%d\n",n, sx,s,OK);
return n;
......
......@@ -208,6 +208,7 @@
#include "multi10359.h"
#include "mt9x001.h"
#include "mt9f002.h"
#include "lepton.h"
#include "gamma_tables.h"
#include "quantization_tables.h"
//#include "latency.h"
......@@ -378,6 +379,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
int qperiod;
int i2cbytes;
int mux,sens;
int fpga_interface = x393_sensor_interface();
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
......@@ -413,14 +415,15 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
if ((mux == SENSOR_NONE) && (sens == SENSOR_NONE))
return 0; // no sensor/mux enabled on this port
//TODO NC393: turn on both sequencers why MRST is active, then i2c frame will definitely match ? Or is it already done in FPGA?
//TODO NC393: turn on both sequencers while MRST is active, then i2c frame will definitely match ? Or is it already done in FPGA?
dev_dbg(g_dev_ptr,"Restarting both command and i2c sequencers for port %d\n",sensor_port);
sequencer_stop_run_reset(sensor_port, SEQ_CMD_RESET);
sequencer_stop_run_reset(sensor_port, SEQ_CMD_RUN); // also programs status update
i2c_stop_run_reset (sensor_port, I2C_CMD_RESET);
dev_dbg(g_dev_ptr,"Setting i2c drive mode for port %d\n",sensor_port);
// dev_dbg(g_dev_ptr,"Setting i2c drive mode for port %d\n",sensor_port);
dev_info(g_dev_ptr,"Setting i2c drive mode for port %d\n",sensor_port);
i2c_drive_mode (sensor_port, SDA_DRIVE_HIGH, SDA_RELEASE);
i2c_stop_run_reset (sensor_port, I2C_CMD_RUN); // also programs status update
......@@ -453,6 +456,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
//mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type
if (mux != SENSOR_NONE) {
if (fpga_interface == FPGA_PAR12) {
dev_dbg(g_dev_ptr,"Mux mode for port %d is %d, tryng 10359\n",sensor_port, mux);
MDP(DBGB_PADD, sensor_port,"Mux mode for port %d is %d, tryng 10359\n",sensor_port, mux)
// try multisensor here (before removing MRST)
......@@ -465,6 +469,9 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
} else {
dev_dbg(g_dev_ptr,"Incompatible FPGA interface for 10359 on port %d\n",sensor_port);
}
} else {
dev_dbg(g_dev_ptr,"Mux mode for port %d SENSOR_NONE, skipping 10359 detection\n",sensor_port);
......@@ -473,7 +480,8 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
//if ((thispars->pars[P_SENSOR]==0) || // multisensor not detected
// ((thispars->pars[P_SENSOR] & SENSOR_MASK) == SENSOR_MT9X001)) { // or is (from DT) SENSOR_MT9X001
if ((thispars->pars[P_SENSOR]==0) && // multisensor not detected
if ((fpga_interface == FPGA_PAR12) &&
(thispars->pars[P_SENSOR]==0) && // multisensor not detected
(((sens & SENSOR_MASK) == SENSOR_MT9X001) || // and from DT it is some SENSOR_MT9*001
((sens & SENSOR_MASK) == SENSOR_MT9P006) )) { // or SENSOR_MT9P006 or friends
......@@ -491,21 +499,26 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
}
if ((thispars->pars[P_SENSOR]==0) &&
if ( (fpga_interface == FPGA_HISPI) &&
(thispars->pars[P_SENSOR]==0) &&
((sens & SENSOR_MASK) == SENSOR_MT9F002)){
dev_dbg(g_dev_ptr,"trying MT9F002, port=%d\n",sensor_port);
MDP(DBGB_PADD, sensor_port,"trying MT9F002, port=%d\n",sensor_port)
// TODO: move to sensor driver
// ************************************************************************************************
// ********************************* MT9x00x SENSOR (5MP) *****************************************
// ************************************************************************************************
mt9f002_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16);
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
}
if ( (fpga_interface == FPGA_VOSPI) &&
(thispars->pars[P_SENSOR]==0) &&
((sens & SENSOR_MASK) == SENSOR_LEPTON35)){
dev_dbg(g_dev_ptr,"trying Lepton 3.5, port=%d\n",sensor_port);
dev_info(g_dev_ptr,"trying Lepton 3.5, port=%d\n",sensor_port);
MDP(DBGB_PADD, sensor_port,"trying Lepton 3.5, port=%d\n",sensor_port)
lepton_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16);
}
//setFramePar(sensor_port, thispars, P_CLK_FPGA, 200000000); // FIXME: NC393
setFramePar(sensor_port, thispars, P_CLK_FPGA, 240000000);
......@@ -518,8 +531,6 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000);
}
if (thispars->pars[P_SENSOR] == SENSOR_DETECT) {
sensor->sensorType=SENSOR_NONE; // to prevent from initializing again
dev_dbg(g_dev_ptr,"No image sensor found\n");
......@@ -981,7 +992,7 @@ return 0;
/** Program sensor WOI and mirroring
*
* As different sensors may produce "bad frames" for differnt WOI changes (i.e. MT9P001 seems to do fine with FLIP, but not WOI_WIDTH)
* As different sensors may produce "bad frames" for different WOI changes (i.e. MT9P001 seems to do fine with FLIP, but not WOI_WIDTH)
* pgm_window and pgm_window_safe will do the same - they will just be called with different latencies and with compressor stopped) */
int pgm_window (int sensor_port, ///< sensor port number (0..3)
struct sensor_t * sensor, ///< sensor static parameters (capabilities)
......@@ -1027,6 +1038,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
struct frameparspair_t pars_to_update[18]; // 15 needed, increase if more entries will be added
int nupdate=0;
int clearHeight;
int tile_vert = X393_TILEVERT;
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n", sensor_port,frame16);
dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_WOI_HEIGHT]=%lx thispars->pars[P_WOI_WIDTH]=%lx\n", sensor_port,thispars->pars[P_WOI_HEIGHT], thispars->pars[P_WOI_WIDTH]);
// if (GLOBALPARS(G_SENS_AVAIL) ) multisensor_pgm_window_common0 (sensor, thispars, prevpars, frame16);
......@@ -1034,6 +1046,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
sensor_width= thispars->pars[P_SENSOR_WIDTH];
sensor_height=thispars->pars[P_SENSOR_HEIGHT];
oversize=thispars->pars[P_OVERSIZE];
// default is good for JP4x, raw
is_color=1;
margins = 0;
switch (thispars->pars[P_COLOR] & 0x0f){
......@@ -1044,6 +1057,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
case COLORMODE_COLOR:
case COLORMODE_COLOR20:
margins = COLOR_MARGINS;
break;
case COLORMODE_RAW:
tile_vert = 1;
}
// flips changed?
if (FRAMEPAR_MODIFIED(P_FLIPH)) {
......@@ -1126,9 +1142,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
}
} else {
if ((!oversize ) && (height > sensor_height)) height=sensor_height;
height= ((height/dv)/X393_TILEVERT) * X393_TILEVERT; // divided by dv (before multisensor options)
height= ((height/dv)/tile_vert) * tile_vert; // divided by dv (before multisensor options)
// suppose minimal height refers to decimated output
while (height < sensor->minHeight) height+=X393_TILEVERT;
while (height < sensor->minHeight) height+=tile_vert;
if (unlikely(thispars->pars[P_SENSOR_PIXV] != height+(2 * margins)))
SETFRAMEPARS_SET(P_SENSOR_PIXV, height+(2 * margins)); ///full height for the sensor (after decimation), including margins
height*=dv;
......@@ -1482,7 +1498,7 @@ int pgm_sensorin (int sensor_port, ///< sensor port number (0..3
}
if (FRAMEPAR_MODIFIED(P_BITS)){
sens_mode.bit16 = thispars->pars[P_BITS];
sens_mode.bit16 = (thispars->pars[P_BITS] > 8);
sens_mode.bit16_set = 1;
X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mode, sens_mode);
dev_dbg(g_dev_ptr,"{%d} X393_SEQ_SEND1(0x%x, 0x%x, x393_sens_mode, 0x%x)\n",
......@@ -2073,6 +2089,9 @@ int pgm_memsensor (int sensor_port, ///< sensor port number (
break;
}
width_bursts = (width_marg >> 4) + ((width_marg & 0xf) ? 1 : 0);
if ((thispars->pars[P_COLOR] == COLORMODE_RAW) && (thispars->pars[P_BITS] > 8)){
width_bursts *= 2;
}
dev_dbg(g_dev_ptr,"PGM_MEMSENSOR: sport=%d width_burts=%d width_marg=%d height_marg=%d left_margin=%d top_margin=%d\n",
sensor_port,
......@@ -2184,7 +2203,9 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number (
int cmprs_top = 0; // 1 for JPEG18 only, 0 for others (also is used for compressor left)
int tile_width; // in bursts, 2 for those with overlap (height>16), 4 with heigh==16
int tile_height; // 16/18 (20 not yet implemented)
x393_cmprs_frame_format_t cmprs_frame_format ={.d32=0};
int compressor_memory_height;
x393_cmprs_frame_format_t cmprs_frame_format = {.d32=0};
x393_cmprs_mode_t cmprs_mode = {.d32=0}; // setting just height 4 LSBs
dev_dbg(g_dev_ptr,"{%d} frame16=%d, pars[P_COLOR]=0x%x\n",sensor_port,frame16, (int)thispars->pars[P_COLOR]);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
......@@ -2192,8 +2213,29 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number (
width_marg = thispars->pars[P_ACTUAL_WIDTH];
height_marg = thispars->pars[P_ACTUAL_HEIGHT];
// NC393: maybe add later monochrome mode with small tiles?
cmprs_frame_format.num_macro_cols_m1 = (width_marg>> 4) - 1; // before adding margins
cmprs_frame_format.num_macro_rows_m1 = (height_marg>> 4) - 1; // before adding margins;
if ((thispars->pars[P_COLOR] == COLORMODE_RAW) && (thispars->pars[P_BITS] > 8)){
cmprs_frame_format.num_macro_cols_m1 = ((width_marg>> 4) << 1) - 1; // before adding margins
} else {
cmprs_frame_format.num_macro_cols_m1 = (width_marg>> 4) - 1; // before adding margins
}
if (thispars->pars[P_COLOR] == COLORMODE_RAW){
compressor_memory_height = height_marg;
cmprs_frame_format.num_macro_rows_m1 = (height_marg -1) >> 4; // before adding margins;
cmprs_mode.rows_lsb = (height_marg -1) & 0xf;
cmprs_mode.rows_lsb_set = 1;
// 4 LSBs of the window height are in compressor mode register
X393_SEQ_SEND1 (sensor_port, frame16, x393_cmprs_control_reg, cmprs_mode);
dev_dbg(g_dev_ptr,"{%d} X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",
sensor_port, sensor_port, frame16, cmprs_mode.d32);
MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",
sensor_port, frame16, cmprs_mode.d32)
} else {
cmprs_frame_format.num_macro_rows_m1 = (height_marg>> 4) - 1; // before adding margins;
compressor_memory_height = (cmprs_frame_format.num_macro_rows_m1 + 1) << 4;
}
switch(thispars->pars[P_COLOR]){
case COLORMODE_COLOR:
......@@ -2218,6 +2260,9 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number (
}
width_bursts = (width_marg >> 4) + ((width_marg & 0xf) ? 1 : 0);
if ((thispars->pars[P_COLOR] == COLORMODE_RAW) && (thispars->pars[P_BITS] > 8)){
width_bursts *= 2;
}
// Adjusting for tile width. TODO: probably not needed, handled in FPGA - verify (and remove 2 next lines)
if (width_bursts & 1) width_bursts++;
if ((tile_width>2) && (width_bursts & 2)) width_bursts += 2;
......@@ -2239,7 +2284,7 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number (
setup_compressor_memory (sensor_port, // sensor port number (0..3)
width_bursts, // 13-bit - in 8*16=128 bit bursts
(cmprs_frame_format.num_macro_rows_m1 + 1) << 4,
compressor_memory_height, // (cmprs_frame_format.num_macro_rows_m1 + 1) << 4,
// height_marg, // 16-bit window height (in scan lines)
0, // 13-bit window left margin in 8-bursts (16 bytes)
cmprs_top, // 16-bit window top margin (in scan lines
......@@ -2314,7 +2359,7 @@ int pgm_compmode (int sensor_port, ///< sensor port number (0..3
if (!jpeg_htable_is_programmed(sensor_port)) jpeg_htable_fpga_pgm (sensor_port);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
// x393cmd = (frame16<0)? ASAP: ABSOLUTE;
if (FRAMEPAR_MODIFIED(P_COLOR)) {
if (FRAMEPAR_MODIFIED(P_COLOR) || FRAMEPAR_MODIFIED(P_BITS)) {
switch (thispars->pars[P_COLOR] & 0x0f){
case COLORMODE_MONO6: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_MONO6; break;
case COLORMODE_COLOR: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_JPEG18; break;
......@@ -2328,6 +2373,10 @@ int pgm_compmode (int sensor_port, ///< sensor port number (0..3
case COLORMODE_JP4DIFF2: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_JP4DIFFDIV2; break;
case COLORMODE_JP4HDR2: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2; break;
case COLORMODE_MONO4: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_MONO4; break;
case COLORMODE_RAW: cmprs_mode.cmode = X393_CMPRS_CBIT_CMODE_RAW;
cmprs_mode.raw_be16 = (thispars->pars[P_BITS] > 8);
cmprs_mode.raw_be16_set = 1;
break;
}
cmprs_mode.cmode_set = 1;
// TODO: Modify left margin by 1 for COLORMODE_COLOR !
......@@ -2871,6 +2920,7 @@ int pgm_comprestart(int sensor_port, ///< sensor port number (0..3
int extra_pages;
int disable_need = 1; // TODO: Use some G_* parameter
int reset_frame;
int raw_mode;
x393_cmprs_mode_t cmprs_mode = {.d32=0};
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
......@@ -2887,15 +2937,21 @@ int pgm_comprestart(int sensor_port, ///< sensor port number (0..3
case COLORMODE_COLOR:
case COLORMODE_COLOR20:
extra_pages = 1;
raw_mode = 0;
break;
default:
case COLORMODE_RAW:
extra_pages = 0;
raw_mode = 1;
break;
default:
extra_pages = 0; // including raw mode
raw_mode = 0;
}
// Compressor memory can be stopped, run single (next frame) or run continuously
// Compressor itself can run in standalone mode 2 (when sensor is stopped/single) or normal mode "3" (X393_CMPRS_CBIT_RUN_ENABLE)
// program compressor mode - normal run (3) or standalone(2)
switch (thispars->pars[P_COMPRESSOR_RUN]) {
case COMPRESSOR_RUN_STOP:
case COMPRESSOR_RUN_STOP: // will never get here after if (thispars->pars[P_COMPRESSOR_RUN]==0) {... return 0;} ?
cmprs_mode.run = X393_CMPRS_CBIT_RUN_DISABLE;
break;
case COMPRESSOR_RUN_SINGLE:
......@@ -2906,13 +2962,14 @@ int pgm_comprestart(int sensor_port, ///< sensor port number (0..3
cmprs_mode.run_set = 1;
// turn comressor off first
if (thispars->pars[P_COMPRESSOR_RUN] == COMPRESSOR_RUN_STOP) {
if (thispars->pars[P_COMPRESSOR_RUN] == COMPRESSOR_RUN_STOP) { // will never get here after if (thispars->pars[P_COMPRESSOR_RUN]==0) {... return 0;} ?
X393_SEQ_SEND1 (sensor_port, frame16, x393_cmprs_control_reg, cmprs_mode);
}
// enable memory after the compressor, same latency
control_compressor_memory (sensor_port,
thispars->pars[P_COMPRESSOR_RUN] & 3, // stop/single/run(/reset)
reset_frame,
raw_mode,
extra_pages,
disable_need,
(frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer
......@@ -2976,6 +3033,7 @@ int pgm_compstop (int sensor_port, ///< sensor port number (0..3
{
#ifndef NC353
int extra_pages;
int raw_mode;
int disable_need = 1; // TODO: Use some G_* parameter
x393_cmprs_mode_t cmprs_mode = {.d32=0};
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
......@@ -2985,9 +3043,15 @@ int pgm_compstop (int sensor_port, ///< sensor port number (0..3
case COLORMODE_COLOR:
case COLORMODE_COLOR20:
extra_pages = 1;
raw_mode = 0;
break;
case COLORMODE_RAW:
extra_pages = 0;
raw_mode = 1;
break;
default:
extra_pages = 0;
raw_mode = 0;
}
// Stop compressor (do not propagate frame sync late, finish current frame)
cmprs_mode.run = X393_CMPRS_CBIT_RUN_DISABLE;
......@@ -2999,6 +3063,7 @@ int pgm_compstop (int sensor_port, ///< sensor port number (0..3
control_compressor_memory (sensor_port, // compressor memory off
COMPRESSOR_RUN_STOP,
0, // reset_frame
raw_mode,
extra_pages,
disable_need,
(frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer
......@@ -3042,6 +3107,7 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3
int disable_need = 1; // TODO: Use some G_* parameter
x393_cmprs_mode_t cmprs_mode = {.d32=0};
int reset_frame = 0;
int raw_mode;
// int just_started = 0;
dev_dbg(g_dev_ptr,"{%d} frame16=%d, prevpars->pars[P_COMPRESSOR_RUN]=%d, thispars->pars[P_COMPRESSOR_RUN]=%d \n",
sensor_port,frame16, (int) prevpars->pars[P_COMPRESSOR_RUN], (int) thispars->pars[P_COMPRESSOR_RUN]);
......@@ -3054,9 +3120,15 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3
case COLORMODE_COLOR:
case COLORMODE_COLOR20:
extra_pages = 1;
raw_mode = 0;
break;
case COLORMODE_RAW:
extra_pages = 0;
raw_mode = 1;
break;
default:
extra_pages = 0;
raw_mode = 0;
}
// Compressor memory can be stopped, run single (next frame) or run continuously
// Compressor itself can run in standalone mode 2 (when sensor is stopped/single) or normal mode "3" (X393_CMPRS_CBIT_RUN_ENABLE)
......@@ -3079,6 +3151,7 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3
control_compressor_memory (sensor_port,
thispars->pars[P_COMPRESSOR_RUN] & 3, // stop/single/run(/reset)
reset_frame,
raw_mode,
extra_pages,
disable_need,
(frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer
......
......@@ -450,6 +450,7 @@ extern struct sensor_port_config_t *pSensorPortConfig;
#define SET_SENSOR_MIBPAR_COND_LUT(p,f,i,r,v) {\
int _MINDEX= MULTIREG(p,P_SENSOR_REGS+(r),(i));\
int _I = (i);\
int _ADDR;\
if (_MINDEX) { \
if ((v) != thispars->pars[_MINDEX]) { \
pars_to_update[nupdate ].num= _MINDEX ;\
......@@ -462,7 +463,7 @@ extern struct sensor_port_config_t *pSensorPortConfig;
_I = pSensorPortConfig[(p)].broadcast_addr;\
} \
} \
int _ADDR = pSensorPortConfig[(p)].par2addr[_I][(r)];\
_ADDR = pSensorPortConfig[(p)].par2addr[_I][(r)];\
if (!(_ADDR&0xffff0000)) {\
X3X3_I2C_SEND2_LUT((p), (f), _I, _ADDR, (v));\
}\
......
......@@ -160,14 +160,21 @@ u32 get_compressor_frame(unsigned int chn) ///< Sensor port number (0..3)
* will have offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page)
*/
static struct meta_offsets_t { //
int Image_DateTime; ///< EXIF Date/Time offset
///< Has offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page)
int Photo_DateTimeOriginal; ///< EXIF Date/Time Original offset
int Photo_ExposureTime; ///< EXIF exposure offset
int Image_ImageNumber; ///< EXIF image number offset
int Image_Orientation; ///< EXIF image orientation offset
int Photo_MakerNote; ///< EXIF maker note (custom data for multi-frame composite images) offset
int PageNumber; ///< EXIF subchannel (0..3) number offset
int Image_DateTime; ///< EXIF Date/Time offset
///< Has offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page)
int Photo_DateTimeOriginal; ///< EXIF Date/Time Original offset
int Photo_ExposureTime; ///< EXIF exposure offset
int Image_ImageNumber; ///< EXIF image number offset
int Image_Orientation; ///< EXIF image orientation offset
int Photo_MakerNote; ///< EXIF maker note (custom data for multi-frame composite images) offset
int PageNumber; ///< EXIF subchannel (0..3) number offset
int ImageWidth; ///< TIFF image width (long, 1)
int ImageLength; ///< TIFF image height (long,1)
int Image_BitsPerSample; ///< TIFF bits per sample, now 8 or 16 (short, 1)
int Image_SamplesPerPixel; ///< TIFF samples per pixel, now always 1 (short, 1)
int RowsPerStrip; ///< TIFF now image height (short, 1)
int StripByteCounts ; ///< TIFF with single strip - byte size of the image (W*H*Image_SamplesPerPixel*ceil(Image_BitsPerSample/8)
} meta_offsets;
#ifdef TEST_DISABLE_CODE
......@@ -498,11 +505,12 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, ///< pointer
int index_time = jptr->jpeg_wp - 11;
char time_buff[27];
char * exif_meta_time_string;
// calcualte bayer without flips - extra xor
// calculate bayer without flips - extra xor
int global_flips, extra_flips, bayer;
unsigned char orientations[]="1638274545273816";
unsigned char orientation_short[2];
int maker_offset;
unsigned long width, height, bits;
u32 frame = jptr->frame;
// int frame_index = frame & PASTPARS_SAVE_ENTRIES_MASK;
// NC393: current parameters are valid at compressor done interrupt (after frame sync interrupts latest valid is new frame number - 2
......@@ -523,7 +531,7 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, ///< pointer
global_flips=extra_flips & 3;
}
// calculate bayer without flips
// calculate Bayer without flips
bayer = get_imageParamsFrame(sensor_port, P_COMP_BAYER, frame);
bayer ^= get_imageParamsFrame(sensor_port, P_COMPMOD_BYRSH, frame);
// subtract flips
......@@ -577,6 +585,22 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, ///< pointer
//get_globalParam(G_TASKLET_CTL)
// left 1 long spare (+44)
}
// Tiff-related data:
width = get_imageParamsFrame(sensor_port, P_WOI_WIDTH, frame);
height = get_imageParamsFrame(sensor_port, P_WOI_HEIGHT, frame);
bits = get_imageParamsFrame(sensor_port, P_BITS, frame);
putlong_meta_irq(sensor_port, width, &meta_offsets.ImageWidth, Exif_Image_ImageWidth);
putlong_meta_irq(sensor_port, height, &meta_offsets.ImageLength, Exif_Image_ImageLength);
short_buff[0] = 0;
short_buff[1] = bits; // assuming non 8/16 (10, 12) are OK?
write_meta_irq(sensor_port, short_buff, &meta_offsets.Image_BitsPerSample, Exif_Image_BitsPerSample, 2);
short_buff[1] = 1;
write_meta_irq(sensor_port, short_buff, &meta_offsets.Image_SamplesPerPixel, Exif_Image_SamplesPerPixel, 2);
short_buff[0] = height >> 8;
short_buff[1] = height & 0xff;
write_meta_irq(sensor_port, short_buff, &meta_offsets.RowsPerStrip, Exif_Image_RowsPerStrip, 2);
putlong_meta_irq(sensor_port, height * width * ((bits + 7) >> 3), &meta_offsets.StripByteCounts, Exif_Image_StripByteCounts);
interframe->meta_index=store_meta(sensor_port);
}
......@@ -1235,7 +1259,8 @@ int register_i2c_sensor(int ports_mask) ///< bitmask of the sensor ports to use
bool mux;
bool broadcast_set = false;
dev_dbg(g_dev_ptr,"register_i2c_sensor()\n");
// dev_dbg(g_dev_ptr,"register_i2c_sensor()\n");
dev_info(g_dev_ptr,"register_i2c_sensor()\n");
for(port=0;port<SENSOR_PORTS;port++) if ((1<<port)&ports_mask) {
......@@ -1327,6 +1352,7 @@ int register_i2c_sensor(int ports_mask) ///< bitmask of the sensor ports to use
memcpy(&dev_sensor, class_sensor, sizeof(x393_i2c_device_t));
i2c_page_register(port, LEGACY_READ_PAGE2);
set_xi2c_rdc(&dev_sensor, port, LEGACY_READ_PAGE2);
dev_info(g_dev_ptr,"register_i2c_sensor(): port=%d, page = 0x%x\n", port, LEGACY_READ_PAGE2);
if (mux){
// 'read' recs for 10359
......@@ -1377,7 +1403,8 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use
i2c_page_register(sensor_port, LEGACY_READ_PAGE4);
dev_sensor.data_bytes=4; // for reading 10359 in 32-bit mode
set_xi2c_rdc(&dev_sensor, sensor_port, LEGACY_READ_PAGE4);
dev_dbg(g_dev_ptr, "Initialized sensor i2c for legacy commands, sensor_port= 0x%x\n",sensor_port);
// dev_dbg(g_dev_ptr, "Initialized sensor i2c for legacy commands, sensor_port= 0x%x\n",sensor_port);
dev_info(g_dev_ptr, "Initialized sensor i2c for legacy commands, sensor_port= 0x%x\n",sensor_port);
}
return 0;
/*
......
......@@ -92,10 +92,12 @@ long long get_frame_pos(unsigned int chn, unsigned int pos);
#define LEGACY_READ_PAGE2 0xff
#define LEGACY_READ_PAGE4 0xfe
#define name_10359 "el10359" // Get name from DT (together with port mask)
#define name_sensor "mt9p006" // Get name from DT (together with port mask)
#define name_mt9p006 "mt9p006" // Get name from DT (together with port mask)
#define name_mt9f002 "mt9f002" // Get name from DT (together with port mask)
// never used?
#define name_10359 "el10359" // Get name from DT (together with port mask)
#define name_sensor "mt9p006" // Get name from DT (together with port mask)
#define name_mt9p006 "mt9p006" // Get name from DT (together with port mask)
#define name_mt9f002 "mt9f002" // Get name from DT (together with port mask)
#define name_lepton35 "lepton35" // Get name from DT (together with port mask)
#define I2C359_INC 2 ///< slave address increment between sensors in 10359A board (broadcast, 1,2,3) (7 bits SA)
......
......@@ -698,8 +698,10 @@ void write_xi2c_reg16_abs_asap (int chn, ///< sensor port
int addr, ///< low byte of the register address (high is in the table), 8 bits
u32 data) ///< 16 or 8-bit data (LSB aligned), 16 address only for 16 bit data
{
// u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
// TODO: change to dev_dbg
dev_dbg(sdev, "write_xi2c_reg16_abs_asap(chn=%d, page=0x%x, frame=0x%x addr=0x%x data=0x%x)\n",chn,page,frame,addr,data);
if (frame<0) x393_sensi2c_rel (dw, chn, 0);
else x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK);
}
......
......@@ -26,9 +26,9 @@
#include <linux/errno.h>
#include <linux/fs.h>
//#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
#include "x393.h"
#include "x393_macro.h"
......@@ -89,7 +89,7 @@ static struct class *videomem_dev_class;
// About frame full width:
// https://blog.elphel.com/2015/05/nc393-development-progress-multichannel-memory-controller-for-the-multi-sensor-camera/#Memory_mapping_and_access_types
static struct elphel_video_buf_t buffer_settings = { ///< some default settings, same as in DT
.frame_start = {0x00000000, 0x08000000, 0x10000000, 0x08000000}, /* Frame starts (in bytes) */
.frame_start = {0x00000000, 0x08000000, 0x10000000, 0x18000000}, /* Frame starts (in bytes) */
.frame_full_width = { 8192, 8192, 8192, 8192}, /* Frame full widths (in bytes). 1 memory page is 2048 bytes (128 bursts) */
.frame_height = { 8192, 8192, 8192, 8192}, /* Channel 3 maximal frame height in pixel lines */
.frames_in_buffer = { 2, 2, 2, 2} /* Number of frames in channel 3 buffer */
......@@ -447,15 +447,15 @@ int control_sensor_memory (int num_sensor, ///< sensor port number (0..3)
}
dev_dbg(g_dev_ptr,"{%d} frame16=%d, cmd=%d, x393cms=%d\n",num_sensor,frame16, cmd, (int) x393cmd);
dev_dbg(g_dev_ptr,"mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem, mcntrl_mode.extra_pages,
mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive,
mcntrl_mode.disable_need, mcntrl_mode.skip_too_late);
dev_dbg(g_dev_ptr,"control_sensor_memory mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem,
mcntrl_mode.extra_pages, mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame,
mcntrl_mode.single, mcntrl_mode.repetitive, mcntrl_mode.disable_need, mcntrl_mode.skip_too_late);
MDP(DBGB_VM,num_sensor,"frame16=%d, cmd=%d, x393cms=%d\n",frame16, cmd, (int) x393cmd)
MDP(DBGB_VM,num_sensor,"mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem, mcntrl_mode.extra_pages,
mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive,
mcntrl_mode.disable_need, mcntrl_mode.skip_too_late)
MDP(DBGB_VM,num_sensor,"control_sensor_memory mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem,
mcntrl_mode.extra_pages, mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame,
mcntrl_mode.single, mcntrl_mode.repetitive,mcntrl_mode.disable_need, mcntrl_mode.skip_too_late)
switch (x393cmd){
......@@ -573,6 +573,7 @@ int control_compressor_memory (int num_sensor, ///< sensor port number (0.
int cmd, ///< command: 0 stop, 1 - single, 2 - repetitive, 3 - reset
int reset_frame, ///< reset addresses to the start of frame, reset buffer (1 of 4) pointer.
///< Should only be used if the channel controller was stopped before
int linear, ///< 0 tiled, 1 - linescan (for raw images)
int extra_pages, ///< extra pages needed (1) - number of previous pages to keep in a 4-page buffer
int disable_need, ///< disable "need" (yield to sensor channels - they can not wait)
x393cmd_t x393cmd, ///< how to apply commands - directly or through channel sequencer
......@@ -585,6 +586,7 @@ int control_compressor_memory (int num_sensor, ///< sensor port number (0.
.extra_pages = 1, // [ 4: 3] (0) 2-bit number of extra pages that need to stay (not to be overwritten) in the buffer
.keep_open = 0, // [ 5] (0) (NA in linescan) for 8 or less rows - do not close page between accesses (not used in scanline mode)
.byte32 = 1, // [ 6] (1) (NA in linescan) 32-byte columns (0 - 16-byte), not used in scanline mode
.linear = linear, // [ 7] (1) Use linear mode instead of tiled (for raw image files): extra_pages=0, keep_open=x, byte32=x
.reset_frame = 1, // [ 8] (0) reset frame number
.single = 0, // [ 9] (0) run single frame
.repetitive = 1, // [ 10] (1) run repetitive frames
......@@ -613,15 +615,17 @@ int control_compressor_memory (int num_sensor, ///< sensor port number (0.
return -EINVAL;
}
dev_dbg(g_dev_ptr,"{%d} frame16=%d, cmd=%d, x393cms=%d\n",num_sensor,frame16, cmd, (int) x393cmd);
dev_dbg(g_dev_ptr,"mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem, mcntrl_mode.extra_pages,
mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive,
mcntrl_mode.disable_need, mcntrl_mode.skip_too_late);
dev_dbg(g_dev_ptr,"control_compressor_memory mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, linear=%d, reset_frame=%d, single=%d, repetitive=%d, disable_need=%d, skip_too_late=%d, copy_frame=%d, abort_late=%d)\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem,
mcntrl_mode.extra_pages, mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.linear,
mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive, mcntrl_mode.disable_need,
mcntrl_mode.skip_too_late, mcntrl_mode.copy_frame, mcntrl_mode.abort_late);
MDP(DBGB_VM,num_sensor,"frame16=%d, cmd=%d, x393cms=%d\n",frame16, cmd, (int) x393cmd)
MDP(DBGB_VM,num_sensor,"mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, reset_frame=%d, single=%d,repetitive=%d, disable_need=%d,skip_too_late=%d )\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem, mcntrl_mode.extra_pages,
mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive,
mcntrl_mode.disable_need, mcntrl_mode.skip_too_late)
MDP(DBGB_VM,num_sensor,"control_compressor_memory mode=0x%x (enable=%d, chn_nreset=%d, write_mem=%d, extra_pages=%d, keep_open=%d, byte32=%d, linear=%d, reset_frame=%d, single=%d, repetitive=%d, disable_need=%d, skip_too_late=%d, copy_frame=%d, abort_late=%d)\n",
mcntrl_mode.d32, mcntrl_mode.enable, mcntrl_mode.chn_nreset, mcntrl_mode.write_mem,
mcntrl_mode.extra_pages, mcntrl_mode.keep_open, mcntrl_mode.byte32, mcntrl_mode.linear,
mcntrl_mode.reset_frame, mcntrl_mode.single, mcntrl_mode.repetitive, mcntrl_mode.disable_need,
mcntrl_mode.skip_too_late, mcntrl_mode.copy_frame, mcntrl_mode.abort_late)
switch (x393cmd){
case ASAP:
......
......@@ -32,7 +32,7 @@ int control_sensor_memory (int num_sensor, int cmd, int reset_frame, x393cmd_t
int setup_compressor_memory (int num_sensor, int window_width, int window_height, int window_left,
int window_top, int tile_width, int tile_height, int tile_vstep,
x393cmd_t x393cmd, int frame16);
int control_compressor_memory (int num_sensor, int cmd, int reset_frame, int extra_pages, int disable_need, x393cmd_t x393cmd, int frame16);
int control_compressor_memory (int num_sensor, int cmd, int reset_frame, int linear, int extra_pages, int disable_need, x393cmd_t x393cmd, int frame16);
int frames_in_buffer_minus_one (int num_sensor);
void memchan_enable (int chn, int enable);
......
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