Commit aa3192c4 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+demo scripts

parent 883d6ed0
......@@ -8,32 +8,78 @@ __email__ = "oleg@elphel.com"
import mmap
import struct
# MAP
"""
0x00000 1024*16 struct framepars_t framePars[PARS_FRAMES=16]; ///< Future frame parameters
0x04000 1024 struct framepars_t func2call; ///< func2call.pars[]
/// each parameter has a 32-bit mask of what
/// pgm_function to call other fields not used
0x04400 2048 unsigned long globalPars[NUM_GPAR=2048]; ///< parameters that are not frame-related, their
/// changes do not initiate any actions so they can
/// be mmaped for both R/W
0x04c00 32*2048 struct framepars_past_t pastPars[PASTPARS_SAVE_ENTRIES=(16 << 7)=2048]; ///< parameters of previously acquired frames
0x14c00 1024 unsigned long multiSensIndex[P_MAX_PAR_ROUNDUP=1024]; ///< indexes of individual sensor register shadows
/// (first of 3) - now for all parameters, not just sensor ones
0x15000 1024 unsigned long multiSensRvrsIndex[P_MAX_PAR_ROUNDUP = 1024]; ///< reverse index (to parent) for the multiSensIndex
/// in lower 16 bits, high 16 bits - sensor number
0x15400
85*1024*4 for mmap
"""
class Pars:
# parameters
P_TRIG_MASTER = 3
# ...
P_WOI_WIDTH = 26
P_WOI_HEIGHT = 27
# ...
P_TRIG_PERIOD = 105
# ...
P_FRAME = 136
P_FRAME_PAST = 8
# constants
## frame params queue length
MAX_FRAMES = 16
MAX_FRAMES = 16
MAX_FRAMES_PAST = 512
## 4 bytes per param
BYTE_MODE = 4
BYTE_MODE = 4
## params per frame from queue
PARS_SIZE = 1024
PARS_SIZE = 1024
PARS_SIZE_PAST = 32
## all mem
MMAP_SIZE = MAX_FRAMES*BYTE_MODE*PARS_SIZE # bytes
PARS_OFFSET = 0x0
PARS_OFFSET_PAST = 0x04c00*BYTE_MODE
#MMAP_SIZE = MAX_FRAMES*BYTE_MODE*PARS_SIZE # bytes
#MMAP_SIZE_PAST = MAX_FRAMES*BYTE_MODE*PARS_SIZE # bytes
MMAP_SIZE_ALL = 85*1024*4
ENDIAN = "<" # little, ">" for big
FRMT_BYTES = {1:'B',2:'H',4:'L',8:'Q'}
FMT = ENDIAN+FRMT_BYTES[BYTE_MODE]
#
def __init__(self,filename=""):
# extract port
self.port = filename[len("/dev/frameparsall"):]
with open(filename,"r+b") as fp:
self.data = mmap.mmap(fp.fileno(), self.MMAP_SIZE, offset = 0) # mmap all data
self.data = mmap.mmap(fp.fileno(), self.MMAP_SIZE_ALL, offset = self.PARS_OFFSET) # mmap some data
#self.data_past = mmap.mmap(fp.fileno(), self.MMAP_SIZE_PAST, offset = self.PARS_OFFSET_PAST) # mmap some data
#
def value(self,param,frame):
offset = (frame%self.MAX_FRAMES)*self.PARS_SIZE*self.BYTE_MODE
......@@ -45,10 +91,63 @@ class Pars:
return res
#
def value_past(self,param,frame):
offset = self.PARS_OFFSET_PAST
offset += (frame%self.MAX_FRAMES_PAST)*self.PARS_SIZE_PAST*self.BYTE_MODE
offset += param*self.BYTE_MODE
data = self.data[offset:offset+self.BYTE_MODE]
res = struct.unpack_from(self.FMT,data)[0]
return res
def get_frame_number(self):
with open("/sys/devices/soc0/elphel393-framepars@0/this_frame"+str(self.port)) as file:
data = file.read()
return int(data)
#MAIN
if __name__ == "__main__":
print("Test")
a = Pars('/dev/frameparsall0')
print(" port 0, frame #: "+format(a.value(Pars.P_FRAME,0),'#08x'))
print(" port 0, frame width: "+format(a.value(Pars.P_WOI_WIDTH,0),'#08x'))
print(" port 0, frame height: "+format(a.value(Pars.P_WOI_HEIGHT,0),'#08x'))
frame = a.get_frame_number()
frame = frame - 1
print("OLD FRAME NUMBER: "+"0x{:08x}".format(frame))
# read future pars
print(" port 0, frame #: "+"0x{:08x}".format(a.value(Pars.P_FRAME,frame&0xf)))
print(" port 0, frame width: "+"0x{:08x}".format(a.value(Pars.P_WOI_WIDTH,frame&0xf)))
print(" port 0, frame height: "+"0x{:08x}".format(a.value(Pars.P_WOI_HEIGHT,frame&0xf)))
print(" port 0, past frame number: "+"0x{:08x}".format(a.value_past(Pars.P_FRAME_PAST,frame&0x1ff)))
print(" port 0, past frame number: "+"0x{:08x}".format(a.value_past(Pars.P_FRAME_PAST,(frame-1)&0x1ff)))
print(" port 0, past frame number: "+"0x{:08x}".format(a.value_past(Pars.P_FRAME_PAST,(frame-2)&0x1ff)))
<?php
$BUF_SIZE = 4096;
$VPATH = "/sys/devices/soc0/elphel393-videomem@0"
$MEM_PRE = "$VPATH/membridge_start"
$VFRAME_PRE = "$VPATH/video_frame_number"
$RAWINFO_PRE = "$VPATH/raw_frame_info"
if (isset($argv[1])){
$_GET['sensor_port'] = $argv[1];
}
if (isset($_GET['sensor_port'])){
$sensor_port = $_GET['sensor_port'];
}else{
$sensor_port = 0;
}
// get master
$frame_num = elphel_get_frame($sensor_port);
$master_port = elphel_get_P_value($sensor_port,ELPHEL_TRIG_MASTER)),0);
set_buf_size($sensor_port,$BUF_SIZE);
set_vbuf_position($sensor_port,0);
// waiting for frame is built-in in the driver
copy_vbuf_to_sbuf($sensor_port,$frame_num+1);
// read frame parameters from sysfs
// echo short header
// echo pixels
function set_buf_size($sensor_port,$size){
exec("echo $size > /sys/devices/soc0/elphel393-mem@0/buffer_pages_raw_chn$sensor_port");
}
function set_vbuf_position($sensor_port,$pos){
global $VRAME_PRE;
exec("echo $pos > {$VFRAME_PRE}{$sensor_port}");
}
function copy_vbuf_to_sbuf($port,$frame_num){
global $MEM_PRE
exec("echo $frame_num > {$MEM_PRE}{$sensor_port}");
}
?>
......@@ -18,24 +18,25 @@ import struct
import os
import sys
import subprocess
import time
import xml.etree.ElementTree as ET
import elphel_framepars as EF
MMAP_DATA = True
#MMAP_DATA = False
# globals
MEMPATH = "/sys/devices/soc0/elphel393-mem@0"
VMEMPATH = "/sys/devices/soc0/elphel393-videomem@0"
VPATH = "/sys/devices/soc0/elphel393-videomem@0"
BUF_PRE = MEMPATH+"/buffer_pages_raw_chn"
MEM_PRE = VPATH+"/membridge_start"
VFRAME_PRE = VPATH+"/video_frame_number"
RAWINFO_PRE = VPATH+"/raw_frame_info"
MEM_PRE = VMEMPATH+"/membridge_start"
VFRAME_PRE = VMEMPATH+"/video_frame_number"
VMDEV_PRE = "/dev/image_raw"
# not used here
MEMSTATUS = VMEMPATH+"/membridge_status"
MEMSTATUS = VPATH+"/membridge_status"
# buffer size in 4k pages
# 4096 equals 16MB
# or just calculate based on image sizes
#frameparsPaths = ("/dev/frameparsall0","/dev/frameparsall1","/dev/frameparsall2","/dev/frameparsall3")
BUF_SIZE = 4096
PAGE_SIZE = 4096
......@@ -43,8 +44,11 @@ PAGE_SIZE = 4096
# sbuf - buffer in system memory = cpu RAM
# vbuf - buffer in fpga memory = video memory
def set_sbuf_size(port):
cmd = "echo "+str(BUF_SIZE)+" > "+BUF_PRE+str(port)
# buffer size in 4k pages
# 4096 equals 16MB
# or recalculate based on image dimensions
def set_sbuf_size(port,size):
cmd = "echo "+str(size)+" > /sys/devices/soc0/elphel393-mem@0/buffer_pages_raw_chn"+str(port)
subprocess.call(cmd,shell=True)
def set_vbuf_position(port,pos):
......@@ -56,12 +60,12 @@ def copy_vbuf_to_sbuf(port,frame_number):
subprocess.call(cmd,shell=True)
def save_pixel_array(port,fname):
cmd = "cat "+VMDEV_PRE+str(port)+" > "+fname
cmd = "cat /dev/image_raw"+str(port)+" > "+fname
subprocess.call(cmd,shell=True)
print("Memory dumped into "+fname)
def mmap_pixel_array(port,size):
with open(VMDEV_PRE+str(port),"r+b") as fp:
with open("/dev/image_raw"+str(port),"r+b") as fp:
data = mmap.mmap(fp.fileno(), size, offset = 0) # mmap all data
return data
......@@ -74,26 +78,125 @@ def get_byte_str(data,i):
return "{:02x}".format(res)
#return format(get_byte(data,i),'#02x')
# normally meta is 1 frame behind but can be read after
# membridge transfer is done
def get_timestamp_from_meta(port,frame_number):
tmpfile = "/tmp/meta.xml"
cmd = "wget -qO- 'http://127.0.0.1:"+str(IMGSRV_BASE_PORT+port)+"/meta' > "+tmpfile
subprocess.call(cmd,shell=True)
e = ET.parse(tmpfile).getroot()
for i in e.iter('DateTimeOriginal'):
#run once
ts = i.text.strip("\"")
break
for i in e.iter('ImageNumber'):
#run once
inf = int(i.text.strip("\""))
break
for i in e.iter('currentSensorFrame'):
#run once
csf = int(i.text.strip("\""))
break
print("REF: "+str(frame_number)+" ImageNumber: "+str(inf)+" currentSensorFrame:"+str(csf))
os.remove(tmpfile)
return ts
# MAIN
IMGSRV_BASE_PORT = 2323
mmap_data = []
sensors = []
# First detect how many sensor ports are there
for i in range(4):
path = "/sys/devices/soc0/elphel393-detect_sensors@0/sensor"+str(i)+"0"
if os.path.isfile(path):
with open(path) as f:
if (f.read().strip()!="none"):
sensors.append(i)
print("Available sensors: "+str(sensors))
# Now get which one is the master (from the 1st available sensor)
p = EF.Pars("/dev/frameparsall"+str(sensors[0]))
tmp_frame_num = p.get_frame_number()
trig_master = p.value(p.P_TRIG_MASTER,tmp_frame_num)
trig_master_port = IMGSRV_BASE_PORT+int(trig_master)
trig_period = p.value(p.P_TRIG_PERIOD,tmp_frame_num)
print("TRIG MASTER = "+str(trig_master))
print("TRIG PERIOD = "+str(trig_period)+" us")
# Stop master trigger (not needed)
#cmd = "wget -qO- 'http://127.0.0.1:"+str(trig_master_port)+"/trig/pointers' &> /dev/null"
#print("Stop trigger:")
#subprocess.call(cmd,shell=True)
#
# First set the buffer size and mmap
#
for i in sensors:
size = BUF_SIZE
set_sbuf_size(i,size)
if MMAP_DATA:
mmap_data.append(mmap_pixel_array(i,BUF_SIZE*PAGE_SIZE))
#
# Get pixel data to from fpga(=video) memory to system memory
#
for i in sensors:
# Master port (if not overriden)
p = EF.Pars("/dev/frameparsall"+str(i))
for i in range(2):
print("Port "+str(i)+":")
#frame_num = p.get_frame_number()+1
#print(" frame number: "+str(frame_num))
set_sbuf_size(i)
set_vbuf_position(i,0)
copy_vbuf_to_sbuf(i,0)
# waiting for frame is built-in in the driver
copy_vbuf_to_sbuf(i,tmp_frame_num+1)
# get timestamp
#ts = get_timestamp_from_meta(i,0)
#print(" timestamp: "+ts)
if MMAP_DATA:
mmap_data.append(mmap_pixel_array(i,BUF_SIZE*PAGE_SIZE))
# print the first 16 bytes only
print(" ".join("{:02x}".format(get_byte(mmap_data[i],c)) for c in range(16)))
# print the first 16 bytes for test purposes
print("test output: " +" ".join("{:02x}".format(get_byte(mmap_data[i],c)) for c in range(16)))
# test: hexdump -C /dev/image_raw0
else:
save_pixel_array(i,"/tmp/port"+str(i)+".raw")
# Restore trigger
#print("Restore trigger")
#cmd = "wget -qO- 'http://127.0.0.1/parsedit.php?sensor_port="+str(trig_master)+"&immediate&TRIG_PERIOD="+str(trig_period)+"*1' &> /dev/null"
#subprocess.call(cmd,shell=True)
# debug info (might be useful for some standard raw format headers)
print("Debug, stored raw frames parameters:")
# read raw frames parameters
for i in sensors:
with open(RAWINFO_PRE+str(i)) as f:
print("Port "+str(i)+": ")
# insert 4 spaces before each line of text
print("\n".join(" "+c for c in f.read().strip().split("\n")))
if not MMAP_DATA:
print("Now scp raw files to pc and run bayer2rgb\n")
print("Now scp raw files to pc and run bayer2rgb")
......
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