AXIOM Alpha Software
1 Register Memory Space
Image sensor related registers: 0x60xxxxxx
cmv.func contains the functions to deal with this address space
HDMI related registers: 0x80xxxxxx
hdmi.func contains the functions to deal with this address space
0xU0VWWWWW U = image sensor or HDMI V = register block WWWWW = addresses inside a register block
Register Addresses HDMI:
0x800xxxxx = scan generator 0x801xxxxx = address generator 0x802xxxxx = component matrix 4x4 0x803xxxxx = 4 channel 12bit LUT 0x804xxxxx = HDMI PLL dynamic reconfig
Register Addresses Image Sensor:
0x600xxxxx = CMV SPI registers 0x601xxxxx = address generator/capture control 0x602xxxxx = LVDS input delay registers 0x603xxxxx = column/row noise LUTs
Examples:
0x60000000 = sensor, register block 0, address 0 (CMV register 0)
2 Reading and Writing Sensor Register
Execute the script that contains the sensor interface functions before we can use them:
. ./cmv.func
Set Sensor register 82 to the decimal value "3122"
cmv_reg 82 3122
Read Register 82:
cmv_reg 82
will output:
0x00000C31
2.1 statically linked busybox
http://vserver.13thfloor.at/Stuff/AXIOM/FAKE/
builtin fake devmem
all you need to get it to work is the following:
dd if=/dev/zero of=/tmp/mem bs=1k seek=4M count=1
this will create a sparse 4GB file /tmp/mem, which will be used by the fake devmem values written can be read back, non existing values return 0
/bin/sh and /sbin/devmem both link to busybox on the axiom alpha filesystem so both can be tested with this executeable
3 Capturing an Image
Preparations:
ssh root@*alpha-IP* "./cmv_train2
Capture the image:
ssh root@*alpha-IP* "./cmv_snap2 -e 10ms" | tee snap.raw16 | display -size 4096x3072 -depth 16 gray:-
So we dont need to type the password every time we snap an image:
Install:
sudo apt-get install sshpass
Use:
sshpass -p '1234' ssh root@*alpha-IP* "./cmv_snap2 -e 10ms" | tee snap.raw16 | display -size 4096x3072 -depth 16 gray:-
4 cmv_snap2
./cmv_snap2 -h This is ./cmv_snap2 V1.5 options are: -h print this help message -8 output 8 bit per pixel -b enable black columns -r dump sensor registers -t enable cmv test pattern -e <exp> exposure time -m <val> capture mask and value -n <num> number of frames -s <num> shift values by <num> -B <val> register mapping base -S <val> register mapping size -M <val> buffer memory base -Z <val> buffer memory size -R <fil> load sensor registers -P <pat> idle pattern
"./cmv_snap2 -r" without an -e parameter outputs only registers
5 cmv_hist2
Outputs RAW histogram data of the last captured image. Values are tab separated in 4 columns (Order: GRBG[image flip on], RGGB[image flip off]) with 4096 values (when operating in 12 bit mode) each.
Download: http://vserver.13thfloor.at/Stuff/AXIOM/cmv_io2/cmv_hist2
./cmv_hist2 This is ./cmv_hist2 V1.0 options are: -h print this help message -s acquire snapshot -B <val> register mapping base -S <val> register mapping size -M <val> buffer memory base -Z <val> buffer memory size
5.1 Examples
./cmv_hist2 -s
Acquire new snapshot and output histogram
./cmv_hist2
Acquire histogram from last captured snapshot in memory
6 cmv_train2
Executes the LVDS training routines to align LVDS reading timing. Execute this script when the Axiom Alpha prototype is booted up before you capture any images:
./cmv_train2
./cmv_train2 -h This is ./cmv_train2 V1.0 options are: -h print this help message -a test all bit pattern -B <val> memory mapping base -S <val> memory mapping size -A <val> memory mapping address -P <val> training pattern
7 Post Processing images
7.1 Create RGGB separated color images from raw file:
convert -size 4096x3072 -depth 16 -crop +0+0 -sample 2048x1536 gray:colors_500ms.raw16 gray:colors_500ms_ch0.raw convert -size 4096x3072 -depth 16 -crop -1+0 -sample 2048x1536 gray:colors_500ms.raw16 gray:colors_500ms_ch1.raw convert -size 4096x3072 -depth 16 -crop +0-1 -sample 2048x1536 gray:colors_500ms.raw16 gray:colors_500ms_ch2.raw convert -size 4096x3072 -depth 16 -crop -1-1 -sample 2048x1536 gray:colors_500ms.raw16 gray:colors_500ms_ch3.raw
7.2 Simple debayer with ImageMagick:
For flipped images:
convert \( -size 4096x3072 -depth 16 gray:colors_500ms.raw16 \) \ \( -clone 0 -crop -1-1 \) \( -clone 0 -crop -1+0 \) \( -clone 0 -crop +0-1 \) \ -sample 2048x1536 \( -clone 2,3 -average \) -delete 2,3 -swap 0,1 +swap -combine colors_500ms.png
For unflipped images:
convert \( -size 4096x3072 -depth 16 gray:IT8_incand.raw16 \) \ \( -clone 0 -crop -1-1 \) \( -clone 0 -crop -1+0 \) \( -clone 0 -crop +0-1 \) \ -sample 2048x1536 \( -clone 0,1 -average \) -delete 0,1 +swap -combine IT8_incand.png
7.3 Plot Histogram of Raw Image
Create histogram values file with imagemagick:
convert -size 4096x3072 -depth 16 gray:image.raw16 -format "%c" histogram:info: > histogram.hist
Reformat the file:
gawk -F, '(NF>3) { printf "%d\t%d\n", $2/16, $1 }'
Or all in one command:
convert -size 4096x3072 -depth 16 gray:image.raw16 -format %c histogram:info:- | gawk -F, '(NF>3) { printf "%d\t%d\n", $2/16, $1 }' > histogram.info
Then draw it with this gnuplot script:
set notitle set term svg size 1024, 512 set xlabel "Values" set ylabel "Number of Pixels" set multiplot set obj 1 rectangle behind from screen 0,0 to screen 1,1 set obj 1 fillstyle solid 1.0 fillcolor rgbcolor "white" set xrange[0:4096] set yrange[0:8000] plot 'histogram.info' using 1:2 with lines lc rgb "#FF0000" title "name your curve", \ 'histogram2.info' using 1:2 with lines lc rgb "#FF0000" title "name your curve" unset multiplot
execute the script with:
gnuplot thescript > output.svg
8 chroot environment on Axiom Alpha
Full raspian image is available on the alpha prototype in a changeroot environment to keep the core system free from too much clutter.
Download:
http://vserver.13thfloor.at/Stuff/AXIOM/raspian.tar.xz
Preferably download from the alpha prototype directly and upack into /opt/raspian, moving files to the prototype using Filezilla has produced some problems.
Map required folders:
mount -o bind /proc /opt/raspian/proc mount -o bind /tmp /opt/raspian/tmp
Changeroot:
chroot /opt/raspian/ /bin/bash
9 Live HDMI video output
Init:
./cmv_train3 -a ./setup.sh
Run Video Acquisition:
time ./cmv_snap3 -N 0 -z -e 25ms
Alternative (slower):
while true; do ./cmv_snap3 -z -e 32ms 2>/dev/null; done
10 Update Firmware
u-boot access:
mount /dev/mmcblk0p1 /mnt/
11 Real Time FPN correction
FPN correction supports a 9bit signed value for each column and row.
9 bit signed integer means:
0xFF = 255 (highest possible positive value) 0x1FF = -1 0x100 = -256 (lowest possible negative value
To obtain the correct value (for -7 in this case) to set you can run:
echo $(( -7 & 0x1FF ))
which outputs (in decimal)
505
To set a value use syntax:
devmem address 32 value
or with actual values:
devmem 0x60304000 32 0xFF
Adresses are:
0x60300000 = even columns, 2048 total 0x60304000 = odd columns, 2048 total 0x60308000 = even rows, 2048 total (only first 1576 are used) 0x6030C000 = odd rows, 2048 total (only first 1576 are used)
each row/column address increases by 4 from current to next row/column.
Row/Column 0 is in the top left corner.
11.1 Balance (FPN profiling tool)
Download: http://vserver.13thfloor.at/Stuff/AXIOM/balance
balance can extract a DSNU profile from a darkframes and apply the created profile to correct an image.
Usage:
Extract FPN profile:
./balance -b -o darkframe.raw16 > profile.offsets
Apply FPN profile to image:
./balance -b -O profile.offsets image.raw16 > image_balanced.raw16
Only use the -b parameter if the image uses darkcolumns.
The profile.offsets file format is:
row-numer offset (double) then column number (double)
(3072+4096)x8 = 57344 Bytes = 57KB
One double is 8 bytes (64 bits)
12 Matrix Color Conversation
Each color channel is going through 4 stages that each look like this: (I+A)*E+O
I = input (25bit unsigned) A = adjustment (30bit signed) E = matrix coefficient (18bit signed) O = offset (48bit signed)
The four stages are connected together that the offset of stage N is the output of stage N-1. The offset of stage 1 is set in registers (32-35). The output of stage 4 is the final result.
For each channel that results in the following fomular:
Ri = SUMj ((Ij + Aij) * Eij) + Oi
Which in other words mean the result of matrix (Eij) multiplied with an input vector (Ij + Aij) plus an offset vector (Oi).
Currently all registers (beside input/output) are shortened to 16bit signed (this could be changed easily) values so the matrix is currently limited to 1/256 of the possible accuracy (due to a 8bit shift of the output).
All input /output register are tested for over/underflow and clipped to 12 bit (this can also be disabled).
Setting/Getting Registers:
. ./hdmi.func # load functions
mat_reg 0 # Read value of register 0 = A0 mat_reg 0 1 # Sett value of register 0 (A0) to 1
4x4 matrix coefficients (A0, A1, A2, A3, B0, B1, B2, B3, B4, C0, C1, C2, C3, D0, D1, D2, D3) are mapped to addresses 0 - 15. In registers 16 - 31 there are adjustment values and from 32 - 35 there are 4 offset values.
All values of the 4x4 matrix can be set conveniently with this script:
Syntax:
./mat4_conf.sh A0 A1 A2 A3 B0 B1 B2 B3 B4 C0 C1 C2 C3 D0 D1 D2 D3
Example:
./mat4_conf.sh 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0