Loading py393/x393_cmprs_afi.py +127 −2 Original line number Diff line number Diff line Loading @@ -34,10 +34,10 @@ __status__ = "Development" #import pickle from x393_mem import X393Mem import x393_axi_control_status import x393_sens_cmprs import x393_utils #import time import time import vrlg class X393CmprsAfi(object): DRY_MODE= True # True Loading Loading @@ -82,6 +82,131 @@ class X393CmprsAfi(object): vrlg.CMPRS_AFIMUX_STATUS_CNTRL, mode, seq_num) def afi_mux_get_image_pointer(self, port_afi, channel): """ Returns image pointer in bytes inside the circbuf. Status autoupdate should be already set up, mode = 0 @param port_afi - AFI port (0/1), currently only 0 @param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only @return - displacement to current image pointer in bytes """ # print ("status reg = 0x%x"%(((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) )) # print ("status reg data = 0x%x"%(self.x393_axi_tasks.read_status((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) )) if (self.DRY_MODE): return None return 32*(self.x393_axi_tasks.read_status((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) & 0x3ffffff) def afi_mux_get_image_meta(self, port_afi, channel, cirbuf_start = 0x27a00000, circbuf_len = 0x1000000, verbose = 1): """ Returns image metadata (start, length,timestamp) or null @param port_afi - AFI port (0/1), currently only 0 @param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only @return - memory segments (1 or two) with image data, timestamp in numeric and string format """ print ("x393_sens_cmprs.GLBL_WINDOW = ", x393_sens_cmprs.GLBL_WINDOW) if (self.DRY_MODE): return None CCAM_MMAP_META = 12 # extra bytes included at the end of each frame (last aligned to 32 bytes) CCAM_MMAP_META_LENGTH = 4 # displacement to length frame length data from the end of the 32-byte aligned frame slot CCAM_MMAP_META_USEC = 8 # // (negative) displacement to USEC data - 20 bits (frame timestamp) CCAM_MMAP_META_SEC = 12 # // (negative) displacement to SEC data - 32 bits (frame timestamp) # offs_len32 = 0x20 - CCAM_MMAP_META_LENGTH # 0x1c #from last image 32-byte chunk to lower of 3-byte image length (MSB == 0xff) next_image = self.afi_mux_get_image_pointer(port_afi = port_afi, channel = channel) last_image_chunk = next_image - 0x40 if last_image_chunk < 0: last_image_chunk += circbuf_len len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH)) markerFF = len32 >> 24 if (markerFF != 0xff): print ("Failed to get 0xff marker at offset 0x%08x - length word = 0x%08x)"%(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH) + 3,len32)) return None len32 &= 0xffffff inserted_bytes = (32 - (((len32 % 32) + CCAM_MMAP_META) % 32)) % 32 img_start = last_image_chunk + 32 - CCAM_MMAP_META - inserted_bytes - len32 if img_start < 0: img_start += circbuf_len sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC)) usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC)) fsec=sec + usec/1000000.0 tstr = time.strftime("%b %d %Y %H:%M:%S", time.gmtime(fsec)) segments = ((cirbuf_start + img_start, len32 ),) if (img_start + len32) > circbuf_len: # split in two segments segments = ((cirbuf_start + img_start, circbuf_len - img_start), (cirbuf_start, len32 - (circbuf_len - img_start))) result = {"timestamp": fsec, "timestring": tstr, "segments":segments} if verbose >0 : print ("Inserted bytes after image before meta = 0x%x"%(inserted_bytes)) print ("Image start (relative to cirbuf) = 0x%x"%(img_start)) print ("Image time stamp = %s (%f)"%(tstr, fsec)) for s in segments: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) return result """ >>> hex (0x3dacb * 32) '0x7b5960' >>> hex (0x3dacb * 32 + 0x27a00000) '0x281b5960' print time.strftime("%b %d %Y %H:%M:%S", time.gmtime(1442344402.605793)) #define CCAM_MMAP_META 12 // extra bytes included at the end of each frame (last aligned to 32 bytes) #define CCAM_MMAP_META_LENGTH 4 // displacement to length frame length data from the end of the 32-byte aligned frame slot #define CCAM_MMAP_META_USEC 8 // (negative) displacement to USEC data - 20 bits (frame timestamp) #define CCAM_MMAP_META_SEC 12 // (negative) displacement to SEC data - 32 bits (frame timestamp) ** * @brief Locate area between frames in the circular buffer * @return pointer to interframe parameters structure */ inline struct interframe_params_t* updateIRQ_interframe(void) { int circbuf_size=get_globalParam (G_CIRCBUFSIZE)>>2; int alen = JPEG_wp-9; if (alen<0) alen+=circbuf_size; int jpeg_len=ccam_dma_buf_ptr[alen] & 0xffffff; set_globalParam(G_FRAME_SIZE,jpeg_len); int aframe_params=(alen & 0xfffffff8)- (((jpeg_len + CCAM_MMAP_META + 3) & 0xffffffe0)>>2) /// multiple of 32-byte chunks to subtract -8; /// size of the storage area to be filled before the frame if(aframe_params < 0) aframe_params += circbuf_size; struct interframe_params_t* interframe= (struct interframe_params_t*) &ccam_dma_buf_ptr[aframe_params]; /// should we use memcpy as before here? interframe->frame_length=jpeg_len; interframe->signffff=0xffff; #if ELPHEL_DEBUG_THIS set_globalParam (0x306,get_globalParam (0x306)+1); #endif return interframe; } /** * @brief Fill exif data with the current frame data, save pointer to Exif page in the interframe area """ # def read_mem (self,addr,quiet=1): # ''' # Read 32-bit word from physical memory # @param addr physical byte address # @param quiet - reduce output #self.x393_mem #0x27a00000 # parameter CMPRS_AFIMUX_REG_ADDR0= 'h18, // Uses 4 locations # parameter CMPRS_AFIMUX_REG_ADDR1= 'h1c, // Uses 4 locations def afi_mux_reset (self, port_afi, Loading py393/x393_jpeg.py +57 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ from x393_mem import X393Mem import x393_axi_control_status import x393_utils #import time import x393_sens_cmprs import x393_cmprs_afi import vrlg STD_QUANT_TBLS = { "Y_landscape":( 16, 11, 10, 16, 24, 40, 51, 61, Loading Loading @@ -158,12 +160,16 @@ class X393Jpeg(object): x393_mem=None x393_axi_tasks=None #x393X393AxiControlStatus x393_utils=None x393_cmprs_afi = None verbose=1 def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None): self.DEBUG_MODE= debug_mode self.DRY_MODE= dry_mode self.x393_mem= X393Mem(debug_mode,dry_mode) self.x393_axi_tasks= x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode) self.x393_cmprs_afi = x393_cmprs_afi.X393CmprsAfi(debug_mode,dry_mode) self.x393_utils= x393_utils.X393Utils(debug_mode,dry_mode, saveFileName) # should not overwrite save file path try: self.verbose=vrlg.VERBOSE Loading Loading @@ -564,6 +570,57 @@ class X393Jpeg(object): return {"header":buf, "quantization":qtables["fpga"], "huffman": self.huff_tables[FPGA_HUFFMAN_TABLE]} def jpeg_write(self, file_path = "/www/pages/img.jpeg", channel = 0, y_quality = 100, #80, c_quality = None, portrait = False, color_mode = 0, byrshift = 0, verbose = 1): """ Create JPEG image from the latest acquired in the camera @param file_path - camera file system path @param channel - compressor channel @param y_quality - 1..100 - quantization quality for Y component @param c_quality - 1..100 - quantization quality for color components (None - use y_quality) @param portrait - False - use normal order, True - transpose for portrait mode images @param color_mode - one of the image formats (jpeg, jp4,) @param byrshift - Bayer shift @param verbose - verbose level """ jpeg_data = self.jpegheader_create ( y_quality = y_quality, c_quality = c_quality, portrait = portrait, height = x393_sens_cmprs.GLBL_WINDOW["height"], width = x393_sens_cmprs.GLBL_WINDOW["width"], color_mode = color_mode, byrshift = byrshift, verbose = verbose - 1) meta = self.x393_cmprs_afi.afi_mux_get_image_meta( port_afi = 0, channel = channel, cirbuf_start = x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel], circbuf_len = x393_sens_cmprs.GLBL_CIRCBUF_CHN_SIZE, verbose = 1) print ("meta = ",meta) for s in meta["segments"]: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) with open (file_path, "w+b") as bf: bf.write(jpeg_data["header"]) for s in meta["segments"]: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) self.x393_mem._mem_write_to_file (bf = bf, start_addr = s[0], length = s[1]) bf.write(bytearray((0xff,0xd9))) def jpegheader_write (self, file_path = "jpeg", y_quality = 80, Loading py393/x393_mem.py +30 −16 Original line number Diff line number Diff line Loading @@ -155,7 +155,21 @@ class X393Mem(object): if self.DRY_MODE: print ("Write memory to file is not implemented in non-target mode") return with open(filename, "w+b") as sf: with open(filename, "w+b") as bf: self._mem_write_to_file (bf = bf, start_addr = start_addr, length = length) def _mem_write_to_file (self, bf, start_addr, length): ''' Save physical memory content to a file @param bf - file open in write mode @param start_addr physical byte start address @param length - number of bytes to save ''' if self.DRY_MODE: print ("Write memory to file is not implemented in non-target mode") return with open("/dev/mem", "r+b") as f: first_page = start_addr // self.PAGE_SIZE last_page = (start_addr + length - 1) // self.PAGE_SIZE Loading @@ -170,7 +184,7 @@ class X393Mem(object): if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) sf.write(mm[start_offset:end_offset]) bf.write(mm[start_offset:end_offset]) def mem_clear (self, start_addr, length, word32): ''' Loading py393/x393_sens_cmprs.py +73 −25 Original line number Diff line number Diff line Loading @@ -60,6 +60,14 @@ BUFFER_PAGES_NAME = 'buffer_pages' BUFFER_ADDRESS = None # in bytes BUFFER_LEN = None # in bytes GLBL_CIRCBUF_CHN_SIZE = None GLBL_CIRCBUF_STARTS = None GLBL_CIRCBUF_END = None GLBL_MEMBRIDGE_START = None GLBL_MEMBRIDGE_END = None GLBL_BUFFER_END = None GLBL_WINDOW = None class X393SensCmprs(object): DRY_MODE = True # True DEBUG_MODE = 1 Loading Loading @@ -470,6 +478,47 @@ class X393SensCmprs(object): repet_mode = True, # Normal mode, single trigger - just for debugging TODO: re-assign? trig = False) return True def specify_window (self, window_width = 2592, # 2592 window_height = 1944, # 1944 window_left = 0, # 0 window_top = 0, # 0? 1? ): global GLBL_WINDOW GLBL_WINDOW = {"width": window_width, "height": window_height, "left": window_left, "top": window_top} def specify_phys_memory(self, circbuf_chn_size= 0x1000000, verbose = 1): """ @param circbuf_chn_size - circular buffer size for each channel, in bytes """ global GLBL_CIRCBUF_CHN_SIZE, GLBL_CIRCBUF_STARTS, GLBL_CIRCBUF_END, GLBL_MEMBRIDGE_START, GLBL_MEMBRIDGE_END, GLBL_BUFFER_END circbuf_start = self.get_circbuf_byte_start() GLBL_BUFFER_END= self.get_circbuf_byte_end() GLBL_CIRCBUF_CHN_SIZE = circbuf_chn_size GLBL_CIRCBUF_STARTS=[] for i in range(16): GLBL_CIRCBUF_STARTS.append(circbuf_start + i*circbuf_chn_size) GLBL_CIRCBUF_END = circbuf_start + 4*GLBL_CIRCBUF_CHN_SIZE GLBL_MEMBRIDGE_START = GLBL_CIRCBUF_END GLBL_MEMBRIDGE_END = GLBL_BUFFER_END if verbose >0 : print ("compressor system memory buffers:") print ("circbuf start 0 = 0x%x"%(GLBL_CIRCBUF_STARTS[0])) print ("circbuf start 1 = 0x%x"%(GLBL_CIRCBUF_STARTS[1])) print ("circbuf start 2 = 0x%x"%(GLBL_CIRCBUF_STARTS[2])) print ("circbuf start 3 = 0x%x"%(GLBL_CIRCBUF_STARTS[3])) print ("circbuf end = 0x%x"%(GLBL_BUFFER_END)) print ("membridge start = 0x%x"%(GLBL_MEMBRIDGE_START)) print ("membridge end = 0x%x"%(GLBL_MEMBRIDGE_END)) print ("membridge size = %d bytes"%(GLBL_MEMBRIDGE_END - GLBL_MEMBRIDGE_START)) print ("memory buffer end = 0x%x"%(GLBL_BUFFER_END)) def setup_all_sensors (self, setup_membridge = False, exit_step = None, Loading Loading @@ -532,38 +581,37 @@ class X393SensCmprs(object): @parame verbose - verbose level @return True if all done, False if exited prematurely by exit_step """ global GLBL_CIRCBUF_CHN_SIZE, GLBL_CIRCBUF_STARTS, GLBL_CIRCBUF_END, GLBL_MEMBRIDGE_START, GLBL_MEMBRIDGE_END, GLBL_BUFFER_END, GLBL_WINDOW # camsync_setup ( # 4'hf ); # sensor_mask); # circbuf_start = self.get_circbuf_byte_start() mem_end= self.get_circbuf_byte_end() #circbuf_chn_size circbuf_starts=[] for i in range(16): circbuf_starts.append(circbuf_start + i*circbuf_chn_size) circbuf_end = circbuf_start + 4*circbuf_chn_size membridge_start = circbuf_end membridge_end = mem_end self.specify_phys_memory(circbuf_chn_size = circbuf_chn_size) self.specify_window (window_width = window_width, window_height = window_height, window_left = window_left, window_top = window_top) #TODO: calculate addresses/lengths """ AFI mux is programmed in 32-byte chunks """ afi_cmprs0_sa = circbuf_starts[0] // 32 afi_cmprs1_sa = circbuf_starts[1] // 32 afi_cmprs2_sa = circbuf_starts[2] // 32 afi_cmprs3_sa = circbuf_starts[3] // 32 afi_cmprs_len = circbuf_chn_size // 32 afi_cmprs0_sa = GLBL_CIRCBUF_STARTS[0] // 32 afi_cmprs1_sa = GLBL_CIRCBUF_STARTS[1] // 32 afi_cmprs2_sa = GLBL_CIRCBUF_STARTS[2] // 32 afi_cmprs3_sa = GLBL_CIRCBUF_STARTS[3] // 32 afi_cmprs_len = GLBL_CIRCBUF_CHN_SIZE // 32 if verbose >0 : print ("compressor system memory buffers:") print ("circbuf start 0 = 0x%x"%(circbuf_starts[0])) print ("circbuf start 1 = 0x%x"%(circbuf_starts[1])) print ("circbuf start 2 = 0x%x"%(circbuf_starts[2])) print ("circbuf start 3 = 0x%x"%(circbuf_starts[3])) print ("circbuf end = 0x%x"%(circbuf_end)) print ("membridge start = 0x%x"%(membridge_start)) print ("membridge end = 0x%x"%(membridge_end)) print ("membridge size = %d bytes"%(membridge_end - membridge_start)) print ("memory buffer end = 0x%x"%(mem_end)) print ("circbuf start 0 = 0x%x"%(GLBL_CIRCBUF_STARTS[0])) print ("circbuf start 1 = 0x%x"%(GLBL_CIRCBUF_STARTS[1])) print ("circbuf start 2 = 0x%x"%(GLBL_CIRCBUF_STARTS[2])) print ("circbuf start 3 = 0x%x"%(GLBL_CIRCBUF_STARTS[3])) print ("circbuf end = 0x%x"%(GLBL_BUFFER_END)) print ("membridge start = 0x%x"%(GLBL_MEMBRIDGE_START)) print ("membridge end = 0x%x"%(GLBL_MEMBRIDGE_END)) print ("membridge size = %d bytes"%(GLBL_MEMBRIDGE_END - GLBL_MEMBRIDGE_START)) print ("memory buffer end = 0x%x"%(GLBL_BUFFER_END)) self.program_status_debug (3,0) if setup_membridge: Loading @@ -573,8 +621,8 @@ class X393SensCmprs(object): window_height = window_height, window_left = window_left, window_top = window_top, membridge_start = membridge_start, membridge_end = membridge_end, membridge_start = GLBL_MEMBRIDGE_START, membridge_end = GLBL_MEMBRIDGE_END, verbose = verbose) if sensor_mask & 3: # Need power for sens1 and sens 2 Loading Loading
py393/x393_cmprs_afi.py +127 −2 Original line number Diff line number Diff line Loading @@ -34,10 +34,10 @@ __status__ = "Development" #import pickle from x393_mem import X393Mem import x393_axi_control_status import x393_sens_cmprs import x393_utils #import time import time import vrlg class X393CmprsAfi(object): DRY_MODE= True # True Loading Loading @@ -82,6 +82,131 @@ class X393CmprsAfi(object): vrlg.CMPRS_AFIMUX_STATUS_CNTRL, mode, seq_num) def afi_mux_get_image_pointer(self, port_afi, channel): """ Returns image pointer in bytes inside the circbuf. Status autoupdate should be already set up, mode = 0 @param port_afi - AFI port (0/1), currently only 0 @param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only @return - displacement to current image pointer in bytes """ # print ("status reg = 0x%x"%(((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) )) # print ("status reg data = 0x%x"%(self.x393_axi_tasks.read_status((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) )) if (self.DRY_MODE): return None return 32*(self.x393_axi_tasks.read_status((vrlg.CMPRS_AFIMUX_REG_ADDR0, vrlg.CMPRS_AFIMUX_REG_ADDR1)[port_afi]+channel) & 0x3ffffff) def afi_mux_get_image_meta(self, port_afi, channel, cirbuf_start = 0x27a00000, circbuf_len = 0x1000000, verbose = 1): """ Returns image metadata (start, length,timestamp) or null @param port_afi - AFI port (0/1), currently only 0 @param channel - AFI input channel (0..3) - with 2 AFIs - 0..1 only @return - memory segments (1 or two) with image data, timestamp in numeric and string format """ print ("x393_sens_cmprs.GLBL_WINDOW = ", x393_sens_cmprs.GLBL_WINDOW) if (self.DRY_MODE): return None CCAM_MMAP_META = 12 # extra bytes included at the end of each frame (last aligned to 32 bytes) CCAM_MMAP_META_LENGTH = 4 # displacement to length frame length data from the end of the 32-byte aligned frame slot CCAM_MMAP_META_USEC = 8 # // (negative) displacement to USEC data - 20 bits (frame timestamp) CCAM_MMAP_META_SEC = 12 # // (negative) displacement to SEC data - 32 bits (frame timestamp) # offs_len32 = 0x20 - CCAM_MMAP_META_LENGTH # 0x1c #from last image 32-byte chunk to lower of 3-byte image length (MSB == 0xff) next_image = self.afi_mux_get_image_pointer(port_afi = port_afi, channel = channel) last_image_chunk = next_image - 0x40 if last_image_chunk < 0: last_image_chunk += circbuf_len len32 = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH)) markerFF = len32 >> 24 if (markerFF != 0xff): print ("Failed to get 0xff marker at offset 0x%08x - length word = 0x%08x)"%(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH) + 3,len32)) return None len32 &= 0xffffff inserted_bytes = (32 - (((len32 % 32) + CCAM_MMAP_META) % 32)) % 32 img_start = last_image_chunk + 32 - CCAM_MMAP_META - inserted_bytes - len32 if img_start < 0: img_start += circbuf_len sec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_SEC)) usec = self.x393_mem.read_mem(cirbuf_start + last_image_chunk + (0x20 - CCAM_MMAP_META_USEC)) fsec=sec + usec/1000000.0 tstr = time.strftime("%b %d %Y %H:%M:%S", time.gmtime(fsec)) segments = ((cirbuf_start + img_start, len32 ),) if (img_start + len32) > circbuf_len: # split in two segments segments = ((cirbuf_start + img_start, circbuf_len - img_start), (cirbuf_start, len32 - (circbuf_len - img_start))) result = {"timestamp": fsec, "timestring": tstr, "segments":segments} if verbose >0 : print ("Inserted bytes after image before meta = 0x%x"%(inserted_bytes)) print ("Image start (relative to cirbuf) = 0x%x"%(img_start)) print ("Image time stamp = %s (%f)"%(tstr, fsec)) for s in segments: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) return result """ >>> hex (0x3dacb * 32) '0x7b5960' >>> hex (0x3dacb * 32 + 0x27a00000) '0x281b5960' print time.strftime("%b %d %Y %H:%M:%S", time.gmtime(1442344402.605793)) #define CCAM_MMAP_META 12 // extra bytes included at the end of each frame (last aligned to 32 bytes) #define CCAM_MMAP_META_LENGTH 4 // displacement to length frame length data from the end of the 32-byte aligned frame slot #define CCAM_MMAP_META_USEC 8 // (negative) displacement to USEC data - 20 bits (frame timestamp) #define CCAM_MMAP_META_SEC 12 // (negative) displacement to SEC data - 32 bits (frame timestamp) ** * @brief Locate area between frames in the circular buffer * @return pointer to interframe parameters structure */ inline struct interframe_params_t* updateIRQ_interframe(void) { int circbuf_size=get_globalParam (G_CIRCBUFSIZE)>>2; int alen = JPEG_wp-9; if (alen<0) alen+=circbuf_size; int jpeg_len=ccam_dma_buf_ptr[alen] & 0xffffff; set_globalParam(G_FRAME_SIZE,jpeg_len); int aframe_params=(alen & 0xfffffff8)- (((jpeg_len + CCAM_MMAP_META + 3) & 0xffffffe0)>>2) /// multiple of 32-byte chunks to subtract -8; /// size of the storage area to be filled before the frame if(aframe_params < 0) aframe_params += circbuf_size; struct interframe_params_t* interframe= (struct interframe_params_t*) &ccam_dma_buf_ptr[aframe_params]; /// should we use memcpy as before here? interframe->frame_length=jpeg_len; interframe->signffff=0xffff; #if ELPHEL_DEBUG_THIS set_globalParam (0x306,get_globalParam (0x306)+1); #endif return interframe; } /** * @brief Fill exif data with the current frame data, save pointer to Exif page in the interframe area """ # def read_mem (self,addr,quiet=1): # ''' # Read 32-bit word from physical memory # @param addr physical byte address # @param quiet - reduce output #self.x393_mem #0x27a00000 # parameter CMPRS_AFIMUX_REG_ADDR0= 'h18, // Uses 4 locations # parameter CMPRS_AFIMUX_REG_ADDR1= 'h1c, // Uses 4 locations def afi_mux_reset (self, port_afi, Loading
py393/x393_jpeg.py +57 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ from x393_mem import X393Mem import x393_axi_control_status import x393_utils #import time import x393_sens_cmprs import x393_cmprs_afi import vrlg STD_QUANT_TBLS = { "Y_landscape":( 16, 11, 10, 16, 24, 40, 51, 61, Loading Loading @@ -158,12 +160,16 @@ class X393Jpeg(object): x393_mem=None x393_axi_tasks=None #x393X393AxiControlStatus x393_utils=None x393_cmprs_afi = None verbose=1 def __init__(self, debug_mode=1,dry_mode=True, saveFileName=None): self.DEBUG_MODE= debug_mode self.DRY_MODE= dry_mode self.x393_mem= X393Mem(debug_mode,dry_mode) self.x393_axi_tasks= x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode) self.x393_cmprs_afi = x393_cmprs_afi.X393CmprsAfi(debug_mode,dry_mode) self.x393_utils= x393_utils.X393Utils(debug_mode,dry_mode, saveFileName) # should not overwrite save file path try: self.verbose=vrlg.VERBOSE Loading Loading @@ -564,6 +570,57 @@ class X393Jpeg(object): return {"header":buf, "quantization":qtables["fpga"], "huffman": self.huff_tables[FPGA_HUFFMAN_TABLE]} def jpeg_write(self, file_path = "/www/pages/img.jpeg", channel = 0, y_quality = 100, #80, c_quality = None, portrait = False, color_mode = 0, byrshift = 0, verbose = 1): """ Create JPEG image from the latest acquired in the camera @param file_path - camera file system path @param channel - compressor channel @param y_quality - 1..100 - quantization quality for Y component @param c_quality - 1..100 - quantization quality for color components (None - use y_quality) @param portrait - False - use normal order, True - transpose for portrait mode images @param color_mode - one of the image formats (jpeg, jp4,) @param byrshift - Bayer shift @param verbose - verbose level """ jpeg_data = self.jpegheader_create ( y_quality = y_quality, c_quality = c_quality, portrait = portrait, height = x393_sens_cmprs.GLBL_WINDOW["height"], width = x393_sens_cmprs.GLBL_WINDOW["width"], color_mode = color_mode, byrshift = byrshift, verbose = verbose - 1) meta = self.x393_cmprs_afi.afi_mux_get_image_meta( port_afi = 0, channel = channel, cirbuf_start = x393_sens_cmprs.GLBL_CIRCBUF_STARTS[channel], circbuf_len = x393_sens_cmprs.GLBL_CIRCBUF_CHN_SIZE, verbose = 1) print ("meta = ",meta) for s in meta["segments"]: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) with open (file_path, "w+b") as bf: bf.write(jpeg_data["header"]) for s in meta["segments"]: print ("start_address = 0x%x, length = 0x%x"%(s[0],s[1])) self.x393_mem._mem_write_to_file (bf = bf, start_addr = s[0], length = s[1]) bf.write(bytearray((0xff,0xd9))) def jpegheader_write (self, file_path = "jpeg", y_quality = 80, Loading
py393/x393_mem.py +30 −16 Original line number Diff line number Diff line Loading @@ -155,7 +155,21 @@ class X393Mem(object): if self.DRY_MODE: print ("Write memory to file is not implemented in non-target mode") return with open(filename, "w+b") as sf: with open(filename, "w+b") as bf: self._mem_write_to_file (bf = bf, start_addr = start_addr, length = length) def _mem_write_to_file (self, bf, start_addr, length): ''' Save physical memory content to a file @param bf - file open in write mode @param start_addr physical byte start address @param length - number of bytes to save ''' if self.DRY_MODE: print ("Write memory to file is not implemented in non-target mode") return with open("/dev/mem", "r+b") as f: first_page = start_addr // self.PAGE_SIZE last_page = (start_addr + length - 1) // self.PAGE_SIZE Loading @@ -170,7 +184,7 @@ class X393Mem(object): if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) sf.write(mm[start_offset:end_offset]) bf.write(mm[start_offset:end_offset]) def mem_clear (self, start_addr, length, word32): ''' Loading
py393/x393_sens_cmprs.py +73 −25 Original line number Diff line number Diff line Loading @@ -60,6 +60,14 @@ BUFFER_PAGES_NAME = 'buffer_pages' BUFFER_ADDRESS = None # in bytes BUFFER_LEN = None # in bytes GLBL_CIRCBUF_CHN_SIZE = None GLBL_CIRCBUF_STARTS = None GLBL_CIRCBUF_END = None GLBL_MEMBRIDGE_START = None GLBL_MEMBRIDGE_END = None GLBL_BUFFER_END = None GLBL_WINDOW = None class X393SensCmprs(object): DRY_MODE = True # True DEBUG_MODE = 1 Loading Loading @@ -470,6 +478,47 @@ class X393SensCmprs(object): repet_mode = True, # Normal mode, single trigger - just for debugging TODO: re-assign? trig = False) return True def specify_window (self, window_width = 2592, # 2592 window_height = 1944, # 1944 window_left = 0, # 0 window_top = 0, # 0? 1? ): global GLBL_WINDOW GLBL_WINDOW = {"width": window_width, "height": window_height, "left": window_left, "top": window_top} def specify_phys_memory(self, circbuf_chn_size= 0x1000000, verbose = 1): """ @param circbuf_chn_size - circular buffer size for each channel, in bytes """ global GLBL_CIRCBUF_CHN_SIZE, GLBL_CIRCBUF_STARTS, GLBL_CIRCBUF_END, GLBL_MEMBRIDGE_START, GLBL_MEMBRIDGE_END, GLBL_BUFFER_END circbuf_start = self.get_circbuf_byte_start() GLBL_BUFFER_END= self.get_circbuf_byte_end() GLBL_CIRCBUF_CHN_SIZE = circbuf_chn_size GLBL_CIRCBUF_STARTS=[] for i in range(16): GLBL_CIRCBUF_STARTS.append(circbuf_start + i*circbuf_chn_size) GLBL_CIRCBUF_END = circbuf_start + 4*GLBL_CIRCBUF_CHN_SIZE GLBL_MEMBRIDGE_START = GLBL_CIRCBUF_END GLBL_MEMBRIDGE_END = GLBL_BUFFER_END if verbose >0 : print ("compressor system memory buffers:") print ("circbuf start 0 = 0x%x"%(GLBL_CIRCBUF_STARTS[0])) print ("circbuf start 1 = 0x%x"%(GLBL_CIRCBUF_STARTS[1])) print ("circbuf start 2 = 0x%x"%(GLBL_CIRCBUF_STARTS[2])) print ("circbuf start 3 = 0x%x"%(GLBL_CIRCBUF_STARTS[3])) print ("circbuf end = 0x%x"%(GLBL_BUFFER_END)) print ("membridge start = 0x%x"%(GLBL_MEMBRIDGE_START)) print ("membridge end = 0x%x"%(GLBL_MEMBRIDGE_END)) print ("membridge size = %d bytes"%(GLBL_MEMBRIDGE_END - GLBL_MEMBRIDGE_START)) print ("memory buffer end = 0x%x"%(GLBL_BUFFER_END)) def setup_all_sensors (self, setup_membridge = False, exit_step = None, Loading Loading @@ -532,38 +581,37 @@ class X393SensCmprs(object): @parame verbose - verbose level @return True if all done, False if exited prematurely by exit_step """ global GLBL_CIRCBUF_CHN_SIZE, GLBL_CIRCBUF_STARTS, GLBL_CIRCBUF_END, GLBL_MEMBRIDGE_START, GLBL_MEMBRIDGE_END, GLBL_BUFFER_END, GLBL_WINDOW # camsync_setup ( # 4'hf ); # sensor_mask); # circbuf_start = self.get_circbuf_byte_start() mem_end= self.get_circbuf_byte_end() #circbuf_chn_size circbuf_starts=[] for i in range(16): circbuf_starts.append(circbuf_start + i*circbuf_chn_size) circbuf_end = circbuf_start + 4*circbuf_chn_size membridge_start = circbuf_end membridge_end = mem_end self.specify_phys_memory(circbuf_chn_size = circbuf_chn_size) self.specify_window (window_width = window_width, window_height = window_height, window_left = window_left, window_top = window_top) #TODO: calculate addresses/lengths """ AFI mux is programmed in 32-byte chunks """ afi_cmprs0_sa = circbuf_starts[0] // 32 afi_cmprs1_sa = circbuf_starts[1] // 32 afi_cmprs2_sa = circbuf_starts[2] // 32 afi_cmprs3_sa = circbuf_starts[3] // 32 afi_cmprs_len = circbuf_chn_size // 32 afi_cmprs0_sa = GLBL_CIRCBUF_STARTS[0] // 32 afi_cmprs1_sa = GLBL_CIRCBUF_STARTS[1] // 32 afi_cmprs2_sa = GLBL_CIRCBUF_STARTS[2] // 32 afi_cmprs3_sa = GLBL_CIRCBUF_STARTS[3] // 32 afi_cmprs_len = GLBL_CIRCBUF_CHN_SIZE // 32 if verbose >0 : print ("compressor system memory buffers:") print ("circbuf start 0 = 0x%x"%(circbuf_starts[0])) print ("circbuf start 1 = 0x%x"%(circbuf_starts[1])) print ("circbuf start 2 = 0x%x"%(circbuf_starts[2])) print ("circbuf start 3 = 0x%x"%(circbuf_starts[3])) print ("circbuf end = 0x%x"%(circbuf_end)) print ("membridge start = 0x%x"%(membridge_start)) print ("membridge end = 0x%x"%(membridge_end)) print ("membridge size = %d bytes"%(membridge_end - membridge_start)) print ("memory buffer end = 0x%x"%(mem_end)) print ("circbuf start 0 = 0x%x"%(GLBL_CIRCBUF_STARTS[0])) print ("circbuf start 1 = 0x%x"%(GLBL_CIRCBUF_STARTS[1])) print ("circbuf start 2 = 0x%x"%(GLBL_CIRCBUF_STARTS[2])) print ("circbuf start 3 = 0x%x"%(GLBL_CIRCBUF_STARTS[3])) print ("circbuf end = 0x%x"%(GLBL_BUFFER_END)) print ("membridge start = 0x%x"%(GLBL_MEMBRIDGE_START)) print ("membridge end = 0x%x"%(GLBL_MEMBRIDGE_END)) print ("membridge size = %d bytes"%(GLBL_MEMBRIDGE_END - GLBL_MEMBRIDGE_START)) print ("memory buffer end = 0x%x"%(GLBL_BUFFER_END)) self.program_status_debug (3,0) if setup_membridge: Loading @@ -573,8 +621,8 @@ class X393SensCmprs(object): window_height = window_height, window_left = window_left, window_top = window_top, membridge_start = membridge_start, membridge_end = membridge_end, membridge_start = GLBL_MEMBRIDGE_START, membridge_end = GLBL_MEMBRIDGE_END, verbose = verbose) if sensor_mask & 3: # Need power for sens1 and sens 2 Loading