Commit a2a841fa authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add PageNumber field to Exif and use it as sensor port number storage

parent 97a0469d
...@@ -176,12 +176,24 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi ...@@ -176,12 +176,24 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi
} }
ssize_t minor_max_size(int minor) { //return max file size for different minors ssize_t minor_max_size(int minor) { //return max file size for different minors
switch (minor) { switch (minor) {
case X3X3_EXIF_TEMPLATE: return MAX_EXIF_SIZE; case X3X3_EXIF_TEMPLATE:
case X3X3_EXIF_EXIF: return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1); return MAX_EXIF_SIZE;
case X3X3_EXIF_META: return MAX_EXIF_SIZE; case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_METADIR: return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t); case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_TIME: return sizeof(struct exif_time_t); case X3X3_EXIF_EXIF_CHN_2:
default:return 0; case X3X3_EXIF_EXIF_CHN_3:
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
return MAX_EXIF_SIZE;
case X3X3_EXIF_METADIR:
return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t);
case X3X3_EXIF_TIME:
return sizeof(struct exif_time_t);
default:
return 0;
} }
} }
void exif_invalidate(void) { // 393: OK, only invalidates all ayt once void exif_invalidate(void) { // 393: OK, only invalidates all ayt once
...@@ -231,6 +243,7 @@ int exif_rebuild_chn(int sensor_port, int frames) { ...@@ -231,6 +243,7 @@ int exif_rebuild_chn(int sensor_port, int frames) {
return -1; return -1;
} }
memset(meta_buffer, 0, aexif_meta_size[sensor_port] * (MAX_EXIF_FRAMES+1)); memset(meta_buffer, 0, aexif_meta_size[sensor_port] * (MAX_EXIF_FRAMES+1));
ameta_buffer[sensor_port] = meta_buffer;
aexif_valid[sensor_port] = 1; aexif_valid[sensor_port] = 1;
return 0; return 0;
} }
...@@ -507,7 +520,6 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) { ...@@ -507,7 +520,6 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
int maxsize=minor_max_size(p); int maxsize=minor_max_size(p);
// int sensor_port; // int sensor_port;
int fp; int fp;
switch (orig) { switch (orig) {
case SEEK_SET: case SEEK_SET:
file->f_pos = offset; file->f_pos = offset;
......
...@@ -149,14 +149,15 @@ static struct image_acq_pd_t image_acq_priv; ...@@ -149,14 +149,15 @@ static struct image_acq_pd_t image_acq_priv;
static volatile int JPEG_wp; static volatile int JPEG_wp;
static volatile int JPEG_rp; static volatile int JPEG_rp;
static int fpga_counter_prev=0; /// Previous value of the FPGA transfer counter (to find out if it did change) static int fpga_counter_prev=0; /// Previous value of the FPGA transfer counter (to find out if it did change)
static struct meta_offsets_t { // works like a cache to time save on looking for tags in the directory (forced to recalcualte if does not match) static struct meta_offsets_t { // works like a cache to time save on looking for tags in the directory (forced to recalculate if does not match)
int Image_DateTime; // will have offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page) int Image_DateTime; // will have offset of the Exif_Image_DateTime data in meta page (Exif_Photo_SubSecTime should go immediately after in meta page)
int Photo_DateTimeOriginal; int Photo_DateTimeOriginal;
int Photo_ExposureTime; int Photo_ExposureTime;
int Image_FrameNumber; int Image_FrameNumber;
int Image_Orientation; int Image_Orientation;
int Photo_MakerNote; int Photo_MakerNote;
} meta_offsets; int PageNumber;
} meta_offsets;
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
int camSeqGetJPEG_wp(void) {return JPEG_wp;} int camSeqGetJPEG_wp(void) {return JPEG_wp;}
...@@ -168,7 +169,7 @@ void camSeqSetJPEG_rp(int p) { ...@@ -168,7 +169,7 @@ void camSeqSetJPEG_rp(int p) {
(((get_globalParam(G_CIRCBUFRP) <= get_globalParam(G_CIRCBUFWP))? (((get_globalParam(G_CIRCBUFRP) <= get_globalParam(G_CIRCBUFWP))?
get_globalParam(G_CIRCBUFSIZE):0)+ get_globalParam(G_CIRCBUFRP)) get_globalParam(G_CIRCBUFSIZE):0)+ get_globalParam(G_CIRCBUFRP))
- get_globalParam(G_CIRCBUFWP)); - get_globalParam(G_CIRCBUFWP));
} }
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
int camseq_get_jpeg_wp(unsigned int chn) int camseq_get_jpeg_wp(unsigned int chn)
...@@ -190,7 +191,7 @@ void camseq_set_jpeg_rp(unsigned int chn, int ptr) ...@@ -190,7 +191,7 @@ void camseq_set_jpeg_rp(unsigned int chn, int ptr)
/*! /*!
End of compressor-related code - TODO: move to a separate file? End of compressor-related code - TODO: move to a separate file?
*/ */
static const struct of_device_id elphel393_sensor_of_match[]; static const struct of_device_id elphel393_sensor_of_match[];
static struct sensorproc_t as_sensorproc[SENSOR_PORTS]; // sensor parameters and functions to call static struct sensorproc_t as_sensorproc[SENSOR_PORTS]; // sensor parameters and functions to call
...@@ -251,7 +252,7 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr) ...@@ -251,7 +252,7 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
{ {
phys_addr_t phys_addr; phys_addr_t phys_addr;
void *virt_addr; void *virt_addr;
// int prev_dword; // int prev_dword;
int xferred; /// number of 32-byte chunks transferred since compressor was reset int xferred; /// number of 32-byte chunks transferred since compressor was reset
x393_afimux_status_t stat = x393_afimux0_status(jptr->chn_num); x393_afimux_status_t stat = x393_afimux0_status(jptr->chn_num);
...@@ -275,53 +276,53 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr) ...@@ -275,53 +276,53 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
/* Correct frame length and re-adjust interframe params. /* Correct frame length and re-adjust interframe params.
* This operations was scheduled on previous interrupt. * This operations was scheduled on previous interrupt.
*/ */
// if (jptr->flags & SENS_FLAG_HW_OFF) { // if (jptr->flags & SENS_FLAG_HW_OFF) {
// int len32; // int len32;
// int len32_ptr = jptr->jpeg_wp - INTERFRAME_PARAMS_SZ - 1; // int len32_ptr = jptr->jpeg_wp - INTERFRAME_PARAMS_SZ - 1;
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + DW2BYTE(jptr->jpeg_wp) - CHUNK_SIZE; // phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + DW2BYTE(jptr->jpeg_wp) - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + jptr->jpeg_wp - INTERFRAME_PARAMS_SZ; // virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + jptr->jpeg_wp - INTERFRAME_PARAMS_SZ;
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1)); // outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE); // __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr]; // len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr];
// len32 -= INTERFRAME_PARAMS_SZ; // len32 -= INTERFRAME_PARAMS_SZ;
// circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr] = len32; // circbuf_priv_ptr[jptr->chn_num].buf_ptr[len32_ptr] = len32;
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE); // __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1)); // outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// jptr->flags &= ~SENS_FLAG_HW_OFF; // jptr->flags &= ~SENS_FLAG_HW_OFF;
// } // }
/* Looks like compressor is not writing 32 zero bytes when last frame ends precisely at the /* Looks like compressor is not writing 32 zero bytes when last frame ends precisely at the
* end of buffer. Try to detect this situation and set a flag so that we can overwrite first * end of buffer. Try to detect this situation and set a flag so that we can overwrite first
* 32 bytes of the buffer on next interrupt. These bytes will be used as interframe parameters and current frame length * 32 bytes of the buffer on next interrupt. These bytes will be used as interframe parameters and current frame length
* will be decreased by these 32 bytes. Such a measure will corrupt the frame but preserve the structure. * will be decreased by these 32 bytes. Such a measure will corrupt the frame but preserve the structure.
*/ */
// if (jptr->jpeg_wp == 0) { // if (jptr->jpeg_wp == 0) {
// // we need to invalidate two cache lines in order to // // we need to invalidate two cache lines in order to
// // estimate the situation correctly: one line after the pointer, which should be the line of // // estimate the situation correctly: one line after the pointer, which should be the line of
// // 32 bytes of newly compressed frame(or zero bytes?), and one line before the pointer, which should be the last line of the frame. If this is not done // // 32 bytes of newly compressed frame(or zero bytes?), and one line before the pointer, which should be the last line of the frame. If this is not done
// // then the data read from memory can be incorrect and error detection will give false result. Barrier is set to // // then the data read from memory can be incorrect and error detection will give false result. Barrier is set to
// // prevent compiler from reordering operations. // // prevent compiler from reordering operations.
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr; // phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr; // virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr;
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr); // dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1)); // outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE); // __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + CCAM_DMA_SIZE - CHUNK_SIZE; // phys_addr = circbuf_priv_ptr[jptr->chn_num].phys_addr + CCAM_DMA_SIZE - CHUNK_SIZE;
// virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + BYTE2DW(CCAM_DMA_SIZE - CHUNK_SIZE); // virt_addr = circbuf_priv_ptr[jptr->chn_num].buf_ptr + BYTE2DW(CCAM_DMA_SIZE - CHUNK_SIZE);
// outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1)); // outer_inv_range(phys_addr, phys_addr + (CHUNK_SIZE - 1));
// __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE); // __cpuc_flush_dcache_area(virt_addr, CHUNK_SIZE);
// dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr); // dev_dbg(NULL, "from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p\n", phys_addr, virt_addr);
// barrier(); // barrier();
// prev_dword = X393_BUFFSUB(DW2BYTE(jptr->jpeg_wp), 4); // prev_dword = X393_BUFFSUB(DW2BYTE(jptr->jpeg_wp), 4);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp]); // dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp]);
// dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)]); // dev_dbg(NULL, "circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] = 0x%x\n", circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)]);
//// if (circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] == 0x00 && //// if (circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] == 0x00 &&
// if ((circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] & MARKER_FF) == MARKER_FF) { // if ((circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] & MARKER_FF) == MARKER_FF) {
//// jptr->jpeg_wp += INTERFRAME_PARAMS_SZ; //// jptr->jpeg_wp += INTERFRAME_PARAMS_SZ;
// jptr->flags |= SENS_FLAG_HW_OFF; // jptr->flags |= SENS_FLAG_HW_OFF;
// corrected_offset[jptr->chn_num] += 1; // corrected_offset[jptr->chn_num] += 1;
// } // }
// } // }
// invalidate CPU L1 and L2 caches // invalidate CPU L1 and L2 caches
// the code below was used to find cache coherence issues // the code below was used to find cache coherence issues
...@@ -361,11 +362,11 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr) ...@@ -361,11 +362,11 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr)
inline static void set_default_interframe(struct interframe_params_t *params) inline static void set_default_interframe(struct interframe_params_t *params)
{ {
// params->height = 1936; // params->height = 1936;
// params->width = 2592; // params->width = 2592;
params->height = circbuf_height; params->height = circbuf_height;
params->width = circbuf_width; params->width = circbuf_width;
// params->byrshift = 3; // params->byrshift = 3;
params->byrshift = circbuf_byrshift; params->byrshift = circbuf_byrshift;
params->color = 0; params->color = 0;
params->quality2 = circbuf_quality; params->quality2 = circbuf_quality;
...@@ -422,39 +423,39 @@ inline struct interframe_params_t* updateIRQ_interframe(struct jpeg_ptr_t *jptr) ...@@ -422,39 +423,39 @@ inline struct interframe_params_t* updateIRQ_interframe(struct jpeg_ptr_t *jptr)
* @param interframe pointer to interframe parameters structure * @param interframe pointer to interframe parameters structure
*/ */
inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t* interframe) { inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t* interframe) {
// int index_time = aJPEG_wp-11[sensor_port]; if (index_time<0) index_time+=get_globalParam (sensor_port, G_CIRCBUFSIZE)>>2; unsigned char short_buff[2];
int sensor_port = jptr->chn_num; unsigned int sensor_port = jptr->chn_num;
int index_time = jptr->jpeg_wp - 11; if (index_time<0) index_time+=get_globalParam (sensor_port, G_CIRCBUFSIZE)>>2; int index_time = jptr->jpeg_wp - 11; if (index_time<0) index_time+=get_globalParam (sensor_port, G_CIRCBUFSIZE)>>2;
// struct exif_datetime_t // struct exif_datetime_t
/// calculates datetime([20] and subsec[7], returns pointer to char[27] /// calculates datetime([20] and subsec[7], returns pointer to char[27]
char time_buff[27]; char time_buff[27];
char * exif_meta_time_string=encode_time(time_buff, ccam_dma_buf_ptr[sensor_port][index_time], ccam_dma_buf_ptr[sensor_port][index_time+1]); char * exif_meta_time_string=encode_time(time_buff, ccam_dma_buf_ptr[sensor_port][index_time], ccam_dma_buf_ptr[sensor_port][index_time+1]);
/// may be split in datetime/subsec - now it will not notice missing subseq field in template /// may be split in datetime/subsec - now it will not notice missing subseq field in template
write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Photo_DateTimeOriginal, Exif_Photo_DateTimeOriginal, 27); write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Photo_DateTimeOriginal, Exif_Photo_DateTimeOriginal, 27);
write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Image_DateTime, Exif_Image_DateTime, 20); // may use 27 if room is provided write_meta_irq(sensor_port, exif_meta_time_string, &meta_offsets.Image_DateTime, Exif_Image_DateTime, 20); // may use 27 if room is provided
putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_EXPOS), &meta_offsets.Photo_ExposureTime, Exif_Photo_ExposureTime); putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_EXPOS), &meta_offsets.Photo_ExposureTime, Exif_Photo_ExposureTime);
putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_FRAME), &meta_offsets.Image_FrameNumber, Exif_Image_FrameNumber); putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_FRAME), &meta_offsets.Image_FrameNumber, Exif_Image_FrameNumber);
//Exif_Photo_MakerNote //Exif_Photo_MakerNote
int global_flips=(get_imageParamsThis(sensor_port, P_FLIPH) & 1) | ((get_imageParamsThis(sensor_port, P_FLIPV)<<1) & 2); int global_flips=(get_imageParamsThis(sensor_port, P_FLIPH) & 1) | ((get_imageParamsThis(sensor_port, P_FLIPV)<<1) & 2);
int extra_flips=0; int extra_flips=0;
if (get_imageParamsThis(sensor_port, P_MULTI_MODE)!=0) { if (get_imageParamsThis(sensor_port, P_MULTI_MODE)!=0) {
extra_flips=get_imageParamsThis(sensor_port, P_MULTI_MODE_FLIPS); extra_flips=get_imageParamsThis(sensor_port, P_MULTI_MODE_FLIPS);
global_flips=extra_flips & 3; global_flips=extra_flips & 3;
} }
/* unsigned char orientations[]={1,6,3,8,
2,7,4,5,
4,5,2,7,
3,8,1,6};
*/
unsigned char orientations[]="1638274545273816";
unsigned char orientations[]="1638274545273816";
unsigned char orientation_short[2]; unsigned char orientation_short[2];
orientation_short[0]=0; orientation_short[0]=0;
orientation_short[1]=0xf & orientations[(get_imageParamsThis(sensor_port, P_PORTRAIT)&3) | (global_flips<<2)]; orientation_short[1]=0xf & orientations[(get_imageParamsThis(sensor_port, P_PORTRAIT)&3) | (global_flips<<2)];
write_meta_irq(sensor_port, orientation_short, &meta_offsets.Image_Orientation, Exif_Image_Orientation, 2); write_meta_irq(sensor_port, orientation_short, &meta_offsets.Image_Orientation, Exif_Image_Orientation, 2);
//TODO - use memcpy // write sensor number
// short_buff[0] = 0xf & (jptr->chn_num >> 8);
short_buff[0] = 0;
short_buff[1] = 0xf & sensor_port;
write_meta_irq(sensor_port, short_buff, &meta_offsets.PageNumber, Exif_Image_PageNumber, 2);
//TODO - use memcpy
int maker_offset; int maker_offset;
maker_offset=putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_GAINR), &meta_offsets.Photo_MakerNote, Exif_Photo_MakerNote); maker_offset=putlong_meta_irq(sensor_port, get_imageParamsThis(sensor_port, P_GAINR), &meta_offsets.Photo_MakerNote, Exif_Photo_MakerNote);
if (maker_offset>0) { if (maker_offset>0) {
...@@ -477,12 +478,12 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t* ...@@ -477,12 +478,12 @@ inline void updateIRQ_Exif(struct jpeg_ptr_t *jptr, struct interframe_params_t*
(extra_flips <<24) , maker_offset+40); (extra_flips <<24) , maker_offset+40);
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK1), maker_offset+44); putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK1), maker_offset+44);
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK2), maker_offset+48); putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_MULTI_HEIGHT_BLANK2), maker_offset+48);
// putlong_meta_raw_irq(0x1234567, maker_offset+52); // just testing // putlong_meta_raw_irq(0x1234567, maker_offset+52); // just testing
putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_QUALITY) | ((get_imageParamsThis(sensor_port, P_PORTRAIT)&1)<<7) | (get_imageParamsThis(sensor_port, P_CORING_INDEX)<<16), maker_offset+52); putlong_meta_raw_irq(sensor_port, get_imageParamsThis(sensor_port, P_QUALITY) | ((get_imageParamsThis(sensor_port, P_PORTRAIT)&1)<<7) | (get_imageParamsThis(sensor_port, P_CORING_INDEX)<<16), maker_offset+52);
putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE01), maker_offset+56); // data should be provided by a running daemon putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE01), maker_offset+56); // data should be provided by a running daemon
putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE23), maker_offset+60); putlong_meta_raw_irq(sensor_port, get_globalParam(sensor_port, G_TEMPERATURE23), maker_offset+60);
//get_globalParam(G_TASKLET_CTL) //get_globalParam(G_TASKLET_CTL)
// left 1 long spare (+44) // left 1 long spare (+44)
} }
interframe->meta_index=store_meta(sensor_port); interframe->meta_index=store_meta(sensor_port);
...@@ -538,9 +539,9 @@ static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id) ...@@ -538,9 +539,9 @@ static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id)
{ {
struct jpeg_ptr_t *jptr = dev_id; struct jpeg_ptr_t *jptr = dev_id;
// update_frame_pars(); // update_frame_pars();
wake_up_interruptible(&aframepars_wait_queue[jptr->chn_num]); wake_up_interruptible(&aframepars_wait_queue[jptr->chn_num]);
// tasklet_schedule(&tasklet_fpga); // tasklet_schedule(&tasklet_fpga);
tasklet_schedule(tasklets[jptr->chn_num]); tasklet_schedule(tasklets[jptr->chn_num]);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -571,7 +572,7 @@ static irqreturn_t compressor_irq_handler(int irq, void *dev_id) ...@@ -571,7 +572,7 @@ static irqreturn_t compressor_irq_handler(int irq, void *dev_id)
} }
//wake_up_interruptible(&framepars_wait_queue); //wake_up_interruptible(&framepars_wait_queue);
// tasklet_schedule(&tasklet_fpga); // tasklet_schedule(&tasklet_fpga);
tasklet_schedule(tasklets[jptr->chn_num]); tasklet_schedule(tasklets[jptr->chn_num]);
irq_ctrl.interrupt_cmd = IRQ_CLEAR; irq_ctrl.interrupt_cmd = IRQ_CLEAR;
x393_cmprs_interrupts(irq_ctrl, jptr->chn_num); x393_cmprs_interrupts(irq_ctrl, jptr->chn_num);
...@@ -600,7 +601,7 @@ Modify waiting (LSEEK_*) for histogrames so they will only unfreeze if the histo ...@@ -600,7 +601,7 @@ Modify waiting (LSEEK_*) for histogrames so they will only unfreeze if the histo
For displaying histograms - try use latest available - not waiting fro a particular frame. For displaying histograms - try use latest available - not waiting fro a particular frame.
*/ */
/// HISTOGRAMS_WAKEUP_ALWAYS if 0 will only wakeup processes waiting for histograms when they become available, maybe never if they are disabled /// HISTOGRAMS_WAKEUP_ALWAYS if 0 will only wakeup processes waiting for histograms when they become available, maybe never if they are disabled
/// if defined 1 - will wakeup each frame, regardless of the availability of the histograms /// if defined 1 - will wakeup each frame, regardless of the availability of the histograms
...@@ -640,11 +641,11 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -640,11 +641,11 @@ void tasklet_fpga_function(unsigned long arg) {
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
/// Histograms are available for the previous frame (that is already in circbuf if compressor was running) /// Histograms are available for the previous frame (that is already in circbuf if compressor was running)
/// Is Y histogram needed? /// Is Y histogram needed?
PROFILE_NOW(2); PROFILE_NOW(2);
switch ((tasklet_disable >> TASKLET_CTL_HISTY_BIT) & 7) { switch ((tasklet_disable >> TASKLET_CTL_HISTY_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate case TASKLET_HIST_NEVER: /// never calculate
...@@ -668,71 +669,71 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -668,71 +669,71 @@ void tasklet_fpga_function(unsigned long arg) {
} }
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (hist_en) { if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1] /// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, (1 << COLOR_Y_NUMBER), hash32p, framep); /// 0x2 Green1 set_histograms (prevFrameNumber, (1 << COLOR_Y_NUMBER), hash32p, framep); /// 0x2 Green1
GLOBALPARS(G_HIST_Y_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame GLOBALPARS(G_HIST_Y_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame
PROFILE_NOW(3); PROFILE_NOW(3);
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#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(&hist_y_wait_queue); /// 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(&hist_y_wait_queue); /// wait queue for the G1 histogram (used as Y)
} }
#endif #endif
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
/// Process parameters /// Process parameters
if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) { if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) {
processPars (sensor_port, sensorproc, getThisFrameNumber(sensor_port), get_globalParam(sensor_port, G_MAXAHEAD)); /// program parameters processPars (sensor_port, sensorproc, getThisFrameNumber(sensor_port), get_globalParam(sensor_port, G_MAXAHEAD)); /// program parameters
PROFILE_NOW(4); PROFILE_NOW(4);
} }
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
/// Are C histograms needed? /// Are C histograms needed?
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) { switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate case TASKLET_HIST_NEVER: /// never calculate
hist_en=0; hist_en=0;
break; break;
case TASKLET_HIST_HALF: /// calculate each even (0,2,4,6 frme of 8) case TASKLET_HIST_HALF: /// calculate each even (0,2,4,6 frme of 8)
hist_en= ((thisFrameNumber & 1) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C)); hist_en= ((thisFrameNumber & 1) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break; break;
case TASKLET_HIST_QUATER: /// calculate twice per 8 (0, 4) case TASKLET_HIST_QUATER: /// calculate twice per 8 (0, 4)
hist_en= ((thisFrameNumber & 3) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C)); hist_en= ((thisFrameNumber & 3) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break; break;
case TASKLET_HIST_ONCE: /// calculate once per 8 (0) case TASKLET_HIST_ONCE: /// calculate once per 8 (0)
hist_en= ((thisFrameNumber & 7) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C)); hist_en= ((thisFrameNumber & 7) ==0) || (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break; break;
case TASKLET_HIST_RQONLY: /// calculate only when specifically requested case TASKLET_HIST_RQONLY: /// calculate only when specifically requested
hist_en= (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C)); hist_en= (get_imageParamsPrev(sensor_port, P_HISTRQ) & (1<<HISTRQ_BIT_C));
break; break;
case TASKLET_HIST_ALL: /// calculate each frame case TASKLET_HIST_ALL: /// calculate each frame
default: /// calculate always (safer) default: /// calculate always (safer)
hist_en=1; hist_en=1;
} }
/* /*
GLOBALPARS(0x1040)=((thisFrameNumber & 1) ==0); GLOBALPARS(0x1040)=((thisFrameNumber & 1) ==0);
GLOBALPARS(0x1041)=((thisFrameNumber & 3) ==0); GLOBALPARS(0x1041)=((thisFrameNumber & 3) ==0);
GLOBALPARS(0x1042)=((thisFrameNumber & 7) ==0); GLOBALPARS(0x1042)=((thisFrameNumber & 7) ==0);
GLOBALPARS(0x1043)=hist_en; GLOBALPARS(0x1043)=hist_en;
GLOBALPARS(0x1044)=thisFrameNumber; GLOBALPARS(0x1044)=thisFrameNumber;
*/ */
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (hist_en) { if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1] /// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, 0xf, hash32p, framep); /// all 4 colors, including Y (it will be skipped) set_histograms (prevFrameNumber, 0xf, hash32p, framep); /// all 4 colors, including Y (it will be skipped)
GLOBALPARS(G_HIST_C_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame GLOBALPARS(G_HIST_C_FRAME)=prevFrameNumber; /// histogram corresponds to previous frame
PROFILE_NOW(5); PROFILE_NOW(5);
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#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(&hist_c_wait_queue); /// 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(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
} }
#endif #endif
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
*/ */
#ifndef _ASM_CMOSCAM_H #ifndef _ASM_CMOSCAM_H
#define _ASM_CMOSCAM_HPARS_FRAMES #define _ASM_CMOSCAM_H
#define SAFE_CHECK 1 // perform more verification on the paremeters #define SAFE_CHECK 1 // perform more verification on the paremeters
//#define ELPHEL_DEBUG 0 //global debug on/off in multiple files //#define ELPHEL_DEBUG 0 //global debug on/off in multiple files
//#define ELPHEL_DEBUG_STARTUP 000a4c00 ; //#define ELPHEL_DEBUG_STARTUP 000a4c00 ;
......
...@@ -66,6 +66,8 @@ struct exif_dir_table_t { ...@@ -66,6 +66,8 @@ struct exif_dir_table_t {
// hack, reusing field to keep it protected // hack, reusing field to keep it protected
#define Exif_Image_IPTCNAA 0x083bb #define Exif_Image_IPTCNAA 0x083bb
#define Exif_Image_FrameNumber 0x083bb #define Exif_Image_FrameNumber 0x083bb
// used for sensor number
#define Exif_Image_PageNumber 0x00129
#define Exif_Image_ExifTag 0x08769 #define Exif_Image_ExifTag 0x08769
#define Exif_Image_GPSTag 0x08825 #define Exif_Image_GPSTag 0x08825
...@@ -178,13 +180,32 @@ struct meta_CompassInfo_t { ...@@ -178,13 +180,32 @@ struct meta_CompassInfo_t {
#define Exif_GPSInfo_CompassRoll_Index 0x12 #define Exif_GPSInfo_CompassRoll_Index 0x12
#define Exif_Image_FrameNumber_Index 0x13 #define Exif_Image_FrameNumber_Index 0x13
#define Exif_Image_Orientation_Index 0x14 #define Exif_Image_Orientation_Index 0x14
#define Exif_Photo_MakerNote_Index 0x15 #define Exif_Image_PageNumber_Index 0x15
#define Exif_Photo_MakerNote_Index 0x16
/// update ExifKmlNumber to be total number of *_Index entries /// update ExifKmlNumber to be total number of *_Index entries
#define ExifKmlNumber Exif_Photo_MakerNote_Index+1 #define ExifKmlNumber Exif_Photo_MakerNote_Index+1
//#define EXIF_DEV_NAME "/dev/exif_exif"
#define EXIF_DEV_NAME "/dev/exif_exif"
#define EXIFDIR_DEV_NAME "/dev/exif_metadir" #define EXIFDIR_DEV_NAME "/dev/exif_metadir"
#define EXIFMETA_DEV_NAME "/dev/exif_meta" //#define EXIFMETA_DEV_NAME "/dev/exif_meta"
#endif /**
* @brief This macro is used to construct file names in user space applications. Example
* of usage: <e>const char *exif_file_names[SENSOR_PORTS] = { EXIF_DEV_NAMES };</e>. Then the
* sensor port number can be used to access file name.
*/
#define EXIF_DEV_NAMES "/dev/exif_exif0", \
"/dev/exif_exif1", \
"/dev/exif_exif2", \
"/dev/exif_exif3"
/**
* @brief This macro is used to construct file names in user space applications. Example
* of usage: <e>const char *exifmeta_file_names[SENSOR_PORTS] = { EXIFMETA_DEV_NAMES };</e>. Then
* the sensor port number can be used to access file name.
*/
#define EXIFMETA_DEV_NAMES "/dev/exif_meta0", \
"/dev/exif_meta1", \
"/dev/exif_meta2", \
"/dev/exif_meta3"
#endif /* _ASM_EXIF_H */
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