Commit 922aaa72 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Debugging multi-sensor operation

parent cffce9dc
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -793,7 +793,8 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait)
	int rslt;
	int rslt;
	dev_dbg(g_dev_ptr, "minor = 0x%x\n", minor);
	dev_dbg(g_dev_ptr, "minor = 0x%x\n", minor);


	rslt = circbufValidPointer(&file->f_pos, &fp, chn);
//	rslt = circbufValidPointer(&file->f_pos, &fp, chn);
    rslt = circbufValidPointer(file->f_pos, &fp, chn);
	if (rslt < 0) {
	if (rslt < 0) {
		// not a valid read pointer, probable buffer overrun
		// not a valid read pointer, probable buffer overrun
		dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%llx\n", file->f_pos);
		dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%llx\n", file->f_pos);
+138 −134
Original line number Original line Diff line number Diff line
@@ -110,7 +110,7 @@
// ##include <asm/dma-mapping.h>
// ##include <asm/dma-mapping.h>


#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
//#include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h>
#include <uapi/elphel/exifa.h>
//#include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr
//#include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr
//#include "fpga_io.h"//fpga_table_write_nice
//#include "fpga_io.h"//fpga_table_write_nice
@@ -166,8 +166,8 @@ struct histogram_stuct_t * histograms_p; ///< alias of histogram_stuct_t
/** @brief Global pointer to basic device structure. This pointer is used in debugfs output functions */
/** @brief Global pointer to basic device structure. This pointer is used in debugfs output functions */
static struct device *g_dev_ptr;
static struct device *g_dev_ptr;


wait_queue_head_t hist_y_wait_queue;    ///< wait queue for the G1 histogram (used as Y)
wait_queue_head_t ahist_y_wait_queue[SENSOR_PORTS];    ///< wait queue for the G1 histogram (used as Y)
wait_queue_head_t hist_c_wait_queue;    ///< wait queue for all the other (R,G2,B) histograms (color)
wait_queue_head_t ahist_c_wait_queue[SENSOR_PORTS];    ///< wait queue for all the other (R,G2,B) histograms (color)
void init_histograms(int chn_mask); ///< combined subchannels and ports Save mask to global P-variable
void init_histograms(int chn_mask); ///< combined subchannels and ports Save mask to global P-variable
int histograms_init_hardware(void);
int histograms_init_hardware(void);
static volatile int histograms_initialized = 0; ///< 0 - not initialized, 1 - structures only, 2 structures and hardware NC393: initialize when first used?
static volatile int histograms_initialized = 0; ///< 0 - not initialized, 1 - structures only, 2 structures and hardware NC393: initialize when first used?
@@ -206,7 +206,7 @@ int histograms_check_init(void)
struct histograms_pd {
struct histograms_pd {
    int                minor;
    int                minor;
    unsigned long      frame;             ///< absolute frame number requested
    unsigned long      frame;             ///< absolute frame number requested
    int                frame_index;       ///< histogram fame index (in cache and when accessing through mmap), -1 if invalid,
    int                frame_index;       ///< histogram frame index (in cache and when accessing through mmap), -1 if invalid,
    int                needed;            ///< bits specify what histograms (color, type) are requested
    int                needed;            ///< bits specify what histograms (color, type) are requested
                                          ///<  each group of 4 bits covers 4 colors of the same type:
                                          ///<  each group of 4 bits covers 4 colors of the same type:
                                          ///<  - bits 0..3 - read raw histograms from the FPGA - normally called from IRQ/tasklet (use just 1 color for autoexposure to speed up?)
                                          ///<  - bits 0..3 - read raw histograms from the FPGA - normally called from IRQ/tasklet (use just 1 color for autoexposure to speed up?)
@@ -469,7 +469,7 @@ int get_histograms(int sensor_port, ///< sensor port number (0..3)
    }
    }
    index=GLOBALPARS(sensor_port, G_HIST_LAST_INDEX+sensor_chn); // set_histograms may increment G_HIST_LAST_INDEX+sensor_chn
    index=GLOBALPARS(sensor_port, G_HIST_LAST_INDEX+sensor_chn); // set_histograms may increment G_HIST_LAST_INDEX+sensor_chn
    for (i=0;i<HISTOGRAM_CACHE_NUMBER;i++) {
    for (i=0;i<HISTOGRAM_CACHE_NUMBER;i++) {
        dev_dbg(g_dev_ptr, "index=%d, needed=0x%x\n",index,needed);
        dev_dbg(g_dev_ptr, "hist_indx= %d, index=%d, needed=0x%x\n",hist_indx, index,needed);
        if ((histograms[hist_indx][index].frame <= frame) && ((histograms[hist_indx][index].valid & raw_needed)==raw_needed)) break;
        if ((histograms[hist_indx][index].frame <= frame) && ((histograms[hist_indx][index].valid & raw_needed)==raw_needed)) break;
        index = (index-1) & (HISTOGRAM_CACHE_NUMBER-1);
        index = (index-1) & (HISTOGRAM_CACHE_NUMBER-1);
    }
    }
@@ -725,14 +725,14 @@ loff_t histograms_lseek (struct file * file,
                        dev_dbg(g_dev_ptr, "privData->request_en=0\n");
                        dev_dbg(g_dev_ptr, "privData->request_en=0\n");
                    }
                    }
#if 0
#if 0
            if (privData-> wait_mode)  wait_event_interruptible (hist_c_wait_queue,GLOBALPARS(privData->port,G_HIST_C_FRAME + privData->subchannel)>=offset);
                    if (privData-> wait_mode)  wait_event_interruptible (ahist_c_wait_queue[privData->port],GLOBALPARS(privData->port,G_HIST_C_FRAME + privData->subchannel)>=offset);
            else                       wait_event_interruptible (hist_y_wait_queue,GLOBALPARS(privData->port,G_HIST_Y_FRAME + privData->subchannel)>=offset);
                    else                       wait_event_interruptible (ahist_y_wait_queue[privData->port],GLOBALPARS(privData->port,G_HIST_Y_FRAME + privData->subchannel)>=offset);
#endif
#endif
                    dev_dbg(g_dev_ptr, "Before waiting: frame = 0x%x, offset=0x%x privData-> wait_mode=%d\n",
                    dev_dbg(g_dev_ptr, "Before waiting: frame = 0x%x, offset=0x%x privData-> wait_mode=%d\n",
                            (int) getThisFrameNumber(privData->port), (int) offset, privData-> wait_mode);
                            (int) getThisFrameNumber(privData->port), (int) offset, privData-> wait_mode);
                    // neded next frame after requested (modify php too?)
                    // neded next frame after requested (modify php too?)
            if (privData-> wait_mode)  wait_event_interruptible (hist_c_wait_queue,getThisFrameNumber(privData->port)>offset);
                    if (privData-> wait_mode)  wait_event_interruptible (ahist_c_wait_queue[privData->port],getThisFrameNumber(privData->port)>offset);
            else                       wait_event_interruptible (hist_y_wait_queue,getThisFrameNumber(privData->port)>offset);
                    else                       wait_event_interruptible (ahist_y_wait_queue[privData->port],getThisFrameNumber(privData->port)>offset);
                    dev_dbg(g_dev_ptr, "After waiting: frame = 0x%x\n", (int) getThisFrameNumber(privData->port));
                    dev_dbg(g_dev_ptr, "After waiting: frame = 0x%x\n", (int) getThisFrameNumber(privData->port));
                    privData->frame_index = get_histograms (privData->port, privData->subchannel, offset, privData->needed);
                    privData->frame_index = get_histograms (privData->port, privData->subchannel, offset, privData->needed);
                    if (privData->frame_index <0) {
                    if (privData->frame_index <0) {
@@ -776,12 +776,12 @@ loff_t histograms_lseek (struct file * file,
                            default:
                            default:
                                switch (offset & ~0x1f) {
                                switch (offset & ~0x1f) {
                                case  LSEEK_DAEMON_HIST_Y: // wait for daemon enabled and histograms Y ready
                                case  LSEEK_DAEMON_HIST_Y: // wait for daemon enabled and histograms Y ready
                            dev_dbg(g_dev_ptr, "wait_event_interruptible (hist_y_wait_queue,0x%x & 0x%x)\n",(int) get_imageParamsThis(privData->port, P_DAEMON_EN), (int) (1<<(offset & 0x1f)));
                                    dev_dbg(g_dev_ptr, "wait_event_interruptible (ahist_y_wait_queue[%d],0x%x & 0x%x)\n",privData->port, (int) get_imageParamsThis(privData->port, P_DAEMON_EN), (int) (1<<(offset & 0x1f)));
                            wait_event_interruptible (hist_y_wait_queue, get_imageParamsThis(privData->port, P_DAEMON_EN) & (1<<(offset & 0x1f)));
                                    wait_event_interruptible (ahist_y_wait_queue[privData->port], get_imageParamsThis(privData->port, P_DAEMON_EN) & (1<<(offset & 0x1f)));
                                    break;
                                    break;
                                case  LSEEK_DAEMON_HIST_C: // wait for daemon enabled and histograms Y ready
                                case  LSEEK_DAEMON_HIST_C: // wait for daemon enabled and histograms Y ready
                            dev_dbg(g_dev_ptr, "wait_event_interruptible (hist_c_wait_queue,0x%x & 0x%x)\n",(int) get_imageParamsThis(privData->port, P_DAEMON_EN), (int) (1<<(offset & 0x1f)));
                                    dev_dbg(g_dev_ptr, "wait_event_interruptible (ahist_c_wait_queue[%d],0x%x & 0x%x)\n",privData->port, (int) get_imageParamsThis(privData->port, P_DAEMON_EN), (int) (1<<(offset & 0x1f)));
                            wait_event_interruptible (hist_c_wait_queue, get_imageParamsThis(privData->port, P_DAEMON_EN) & (1<<(offset & 0x1f)));
                                    wait_event_interruptible (ahist_c_wait_queue[privData->port], get_imageParamsThis(privData->port, P_DAEMON_EN) & (1<<(offset & 0x1f)));
                                    break;
                                    break;
                                default:
                                default:
                                    return -EINVAL;
                                    return -EINVAL;
@@ -793,12 +793,14 @@ loff_t histograms_lseek (struct file * file,
                            return -EINVAL;
                            return -EINVAL;
                        }
                        }
                        file->f_pos= HISTOGRAMS_FILE_SIZE;
                        file->f_pos= HISTOGRAMS_FILE_SIZE;
                        dev_dbg(g_dev_ptr, "file->f_pos = HISTOGRAMS_FILE_SIZE = 0x%x\n", (int) file->f_pos);
                        return file->f_pos;
                        return file->f_pos;
                    }
                    }
                    break;
                    break;
                default:  // not SEEK_SET/SEEK_CUR/SEEK_END
                default:  // not SEEK_SET/SEEK_CUR/SEEK_END
                    return -EINVAL;
                    return -EINVAL;
                } // switch (orig)
                } // switch (orig)
    dev_dbg(g_dev_ptr, "file->f_pos = 0x%x\n", (int) file->f_pos);
    return  file->f_pos ;
    return  file->f_pos ;
                default: // other minors
                default: // other minors
                    return -EINVAL;
                    return -EINVAL;
@@ -834,7 +836,7 @@ int histograms_mmap (struct file *file, struct vm_area_struct *vma) {
 * @return 0
 * @return 0
 */
 */
int histograms_init(struct platform_device *pdev) {
int histograms_init(struct platform_device *pdev) {
    int res;
    int res,i;
    int sz, pages;
    int sz, pages;
    struct device *dev = &pdev->dev;
    struct device *dev = &pdev->dev;
//    const struct of_device_id *match; // not yet used
//    const struct of_device_id *match; // not yet used
@@ -846,8 +848,10 @@ int histograms_init(struct platform_device *pdev) {
        return res;
        return res;
    }
    }
    //   init_waitqueue_head(&histograms_wait_queue);
    //   init_waitqueue_head(&histograms_wait_queue);
    init_waitqueue_head(&hist_y_wait_queue);    // wait queue for the G1 histogram (used as Y)
    for (i = 0; i < SENSOR_PORTS; i++) {
    init_waitqueue_head(&hist_c_wait_queue);    // wait queue for all the other (R,G2,B) histograms (color)
        init_waitqueue_head(&ahist_y_wait_queue[i]);    // wait queue for the G1 histogram (used as Y)
        init_waitqueue_head(&ahist_c_wait_queue[i]);    // wait queue for all the other (R,G2,B) histograms (color)
    }
    dev_info(dev, DEV393_NAME(DEV393_HISTOGRAM)": registered MAJOR: %d\n", DEV393_MAJOR(DEV393_HISTOGRAM));
    dev_info(dev, DEV393_NAME(DEV393_HISTOGRAM)": registered MAJOR: %d\n", DEV393_MAJOR(DEV393_HISTOGRAM));
    histograms_initialized = 0;
    histograms_initialized = 0;
    // NC393: Did not find a way to get memory when histograms a first needed:
    // NC393: Did not find a way to get memory when histograms a first needed:
+3 −3
Original line number Original line Diff line number Diff line
@@ -17,12 +17,12 @@
#ifndef HISTOGRAMS_H
#ifndef HISTOGRAMS_H
#define HISTOGRAMS_H
#define HISTOGRAMS_H
#undef ISR_HISTOGRAMS // to histograms-related disable code in ISR - not needed in NC393
#undef ISR_HISTOGRAMS // to histograms-related disable code in ISR - not needed in NC393

#include <uapi/elphel/c313a.h>
// These wait queues will be advanced each frame after the histogram data is transferred to the FPGA.
// These wait queues will be advanced each frame after the histogram data is transferred to the FPGA.
// It will happen even if the corresponding task is disabled, with the only exception:
// It will happen even if the corresponding task is disabled, with the only exception:
// hist_c_wait_queue will not be awaken in the current frame if it is too late (frame counter incremented while serving tasklet)
// hist_c_wait_queue will not be awaken in the current frame if it is too late (frame counter incremented while serving tasklet)
extern wait_queue_head_t hist_y_wait_queue; /// wait queue for the G1 histogram (used as Y)
extern wait_queue_head_t ahist_y_wait_queue[SENSOR_PORTS]; /// wait queue for the G1 histogram (used as Y)
extern wait_queue_head_t hist_c_wait_queue; /// wait queue for all the other (R,G2,B) histograms (color)
extern wait_queue_head_t ahist_c_wait_queue[SENSOR_PORTS]; /// wait queue for all the other (R,G2,B) histograms (color)


// void init_histograms(int chn_mask);
// void init_histograms(int chn_mask);
int histograms_check_init(void);
int histograms_check_init(void);
+4 −4
Original line number Original line Diff line number Diff line
@@ -814,9 +814,9 @@ void tasklet_cmdseq_function(unsigned long arg)
#endif // ifdef ISR_HISTOGRAMS
#endif // ifdef ISR_HISTOGRAMS
#if HISTOGRAMS_WAKEUP_ALWAYS
#if HISTOGRAMS_WAKEUP_ALWAYS
    }
    }
    wake_up_interruptible(&hist_y_wait_queue);    // wait queue for the G1 histogram (used as Y)
    wake_up_interruptible(&ahist_y_wait_queue[sensor_port]);    // wait queue for the G1 histogram (used as Y)
#else
#else
    wake_up_interruptible(&hist_y_wait_queue);    // wait queue for the G1 histogram (used as Y)
    wake_up_interruptible(&ahist_y_wait_queue[sensor_port]);    // wait queue for the G1 histogram (used as Y)
    }
    }
#endif
#endif
    // Process parameters
    // Process parameters
@@ -877,9 +877,9 @@ void tasklet_cmdseq_function(unsigned long arg)
#endif // ifdef ISR_HISTOGRAMS
#endif // ifdef ISR_HISTOGRAMS
#if HISTOGRAMS_WAKEUP_ALWAYS
#if HISTOGRAMS_WAKEUP_ALWAYS
    }
    }
    wake_up_interruptible(&hist_c_wait_queue);     // wait queue for all the other (R,G2,B) histograms (color)
    wake_up_interruptible(&ahist_c_wait_queue[sensor_port]);     // wait queue for all the other (R,G2,B) histograms (color)
#else
#else
        wake_up_interruptible(&hist_c_wait_queue);   // wait queue for all the other (R,G2,B) histograms (color)
        wake_up_interruptible(&ahist_c_wait_queue[sensor_port]);   // wait queue for all the other (R,G2,B) histograms (color)
    }
    }
#endif
#endif
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -213,12 +213,12 @@ int write_compressor_table(int chn, // compressor channel (0..3)
                                    x393cmprs_tables_t type,     // table type (
                                    x393cmprs_tables_t type,     // table type (
                                    int index,
                                    int index,
                                    int num_items,
                                    int num_items,
                                    u32 * data )
                                    unsigned long * data )
{
{
    x393_cmprs_table_addr_t table_addr;
    x393_cmprs_table_addr_t table_addr;
    int i;
    int i;
    table_addr.type = (int) type;
    table_addr.type = (int) type;
    table_addr.addr32 = index * type*4;
    table_addr.addr32 = index * num_items*4;
//    dev_dbg(g_dev_ptr, "table_addr=0x%08x\n", table_addr.d32);
//    dev_dbg(g_dev_ptr, "table_addr=0x%08x\n", table_addr.d32);
    x393_cmprs_tables_address(table_addr, chn);
    x393_cmprs_tables_address(table_addr, chn);
    for (i = 0; i < num_items; i++) {
    for (i = 0; i < num_items; i++) {
Loading