Author |
introduction to camera driver programming |
Raiderski Joined: Jul 03, 2006 Posts: > 500 From: Poland, Hell, Mountains PM, WWW
|
idea for this guide came from old document by SPU where he collected informations about K750, W800 and W810. unfortunately SPU isn't active anymore and his document wasn't updated from long time, that's why I decided to give it a second life and collect our experience in one well-known public place. I used SPU's document as a template, however all hardware related informations are removed. for now I want to make it to be general purpose, in this way it will be useful not only for Sony solution (Cyber-shot family and some other) but also for solutions from other vendors (OmniVision and Samsung Techwin). apart from new things, changes and updates, other informations are translated from Russian to English language. ok, here we go...
- about programming language we know almost everything
- about driver structure we know quite much but some secrets are still undiscovered
- in some way we understand how this structure works - what, why and how. let's call this sequence of driver execution
- most important things are always in hardware registers, therefore we know least about their secrets
all numbers in driver are presented in hexadecimal system, http://en.wikipedia.org/wiki/Hexadecimal
programming language is a simple language with interpreted content. interpretation takes place at the time of use, accuracy of the entire code is not verified before! even if driver contains an error, the execution of commands will continue until an interpreter is not reached incorrect command. if this will happen it marks the whole block of code as incorrect and no longer runs it (at worst, the camera may restart). language is evolving all the time, new commands appeared in K850 and then in C702, also 4 additional data registers since this model
each data register have 4 bytes (32 bit), total number of registers is 16 (r0 - rF) and respectively 20 registers (r0 - rJ) since C702. in registers you can store anything you want and you can use them as you want. one thing you should remember, despite 4 bytes per register not all of them are used by some commands. sometimes it's only 1 byte (first, least significant in register) but it's not a problem
language commands are very easy to understand and use. we have everything what we need - data control, arithmetic operators, code flow control statements, bit operators and some other commands. the most important thing is that programming language is hardware independent. look in drivers for K800 (Sony), K770 (Samsung) and W910 (OmniVision). all at first glance look different but it's not true. it's still the same programming language and driver structures with minor changes adapted to the camera features. this is possible because we have 2 different layers in driver code:
- language commands
- hardware commands
programming language commands and registers have nothing to do with hardware commands and registers. what's the difference? there are only 2 hardware commands:
- send to hardware register
- get from hardware register
not much but these two are really important. three examples:
- we use language commands and registers for calculations, then we can send result of calculations to hardware register
- no calculations, we only want to send value to hardware register
- we want to calculate something but we need value from hardware register, in this case we use 'get from'
no matter of what we have only 2 actions, very important actions:
- from driver - to hardware
- from hardware - to driver - to hardware
last thing about hardware: it's Digital Signal Processor (DSP), small black box where raw data from sensor comes in and JPEG comes out. that's all we need to know for now
driver syntax
at good start basic thing, use // to comment code. everything in one line after // will be ignored
driver can be summarized as well-defined structure with many sequences of code. every sequence consists of 4 elements:
- sequence title
- =
- body (commands)
- ;
BLOCK_NAME = ...;
it's not important how body looks like, it can be formatted in any way. you can write all commands in one line (leave at least one space between commands) or every command in new line
we have 2 types of sequences:
- standard
- macrodefinition (macro)
standard sequences form the basic structure of driver, they are:
- camera power on/off
never ever touch it!
- camera characteristic
- seq_init
executed shortly after opening the camera
- seq_set_prop_*
- seq_get_prop_*
camera properties usually associated with some of the camera features accessible from menu. numeric designation of properties in most cases are consistent in all drivers. code in properties is handling selected features of the camera, it's sort of a bridge between the menu and hardware
- seq_ss_config_*
- seq_vf_config_*
configurations of all photo resolutions and video modes
- seq_vf_*
executed when viewfinder refresh starts or stops
- seq_ss_*
process of taking photo
- seq_pv_*
process of taking photos in burst/BestPic mode
- jpeg_*
macrodefinitions are sequences which do not form the basic structure of driver. their major purpose is to collect sequence of commands which are used very often in code or to cut large sequence of commands to smaller or more logical parts. one thing is certain, macros significantly improve readability of whole code
intention to use macro is signaled by character #
when code interpreter will find character # it will execute macro sequence. macro sequence needs to be defined before the first use in code!
MACRO = ...;
seq_init = ...
#MACRO // OK
#MACRO2 // WRONG!
#MACO // WRONG!
...;
MACRO2 = ...;
macro can receive various parameters. send parameter to macro in ( ) brackets, for example:
seq_init = ...
#MACRO(05)
#MACRO2(03, 02, 05)
#MACRO3($s1 02)
#MACRO4($s0 04, $*3 02)
#MACRO5(#MACRO3($s0 05), #MACRO(01), $+0 05)
...;
this is how you can use received parameters, use !N where N is number of parameter sent in bracket:
MACRO = ...
#SET_REG(22, !0)
...;
MACRO2 = ...
#COM_EVENT(!0, !1)
#SET_REG(!2, 03)
...;
MACRO3 = ...
!0 ...;
MACRO4 = ...
!0 ...
!1 ...;
MACRO5 = ...
!0 ...
!2 ...
!1 ...;
remember that you cannot use parameters as a portion of any language command! you can only use whole commands as a parameters!
MACRO = ...
$s0 !0 // WRONG!
$+0 !0 // WRONG!
$c0 !0 // WRONG!
!1 // OK
...;
seq_init = ...
#MACRO(03, $s1 07)
...;
language commands
NNNN = 16 bit value (00 - FFFF)
NN = 8 bit value (00 - FF)
BB = bit number (00 - 1F)
R = register number (0 - F - J)
X = register number (0 - F - J)
$sR NN
regR = NN, set value NN in register R
$sR %0 is possible
$mX R
regX = regR, copy value from register R to register X
$sR.BB N
set bit BB in register R to value N (0 or 1)
new command since K850
$cR NN
if regR = NN then execute code in branch, otherwise skip to $cl/$cx
compares only 1 byte (first, least significant in register)
$cl
else, alternative branch
$cx
end if, end of branch
$cR.BB N
if bit BB in regR = N (0 or 1) then execute code in branch, otherwise skip to $cl/$cx
new command since K850
$csR NN
if regR < NN then execute code in branch, otherwise skip to $cl/$cx
new command since C702
$cgR NN
if regR > NN then execute code in branch, otherwise skip to $cl/$cx
new command since C702
$+R NN
regR = regR + NN, add value NN to register R
instead of value NN you can use value from register: $+R rX, regR = regR + regX
$+R %0 is possible
$-R NN
regR = regR - NN, subtract value NN from register R
instead of value NN you can use value from register: $-R rX, regR = regR - regX
$-R %0 is possible
$*R NN
regR = regR * NN, multiply value in reg R by NN
instead of value NN you can use value from register: $*R rX, regR = regR * regX
$*R %0 is possible
$/R NN
regR = regR / NN, divide value in reg R by NN
instead of value NN you can use value from register: $/R rX, regR = regR / regX
$/R %0 is possible
$>R N
regR = regR >> N, shift value in register R to right by N bits
not tested with N > 8
$< R N
regR = regR << N, shift value in register R to left by N bits
not tested with N > 8
$bR NN S L
copy L bits from value NN to register R, copy from right to left, start from bit S
not tested with S > 7 and L > 8
$dNNNN
delay (miliseconds) in code execution
$pR NN
regR = current variant of property NN
this command is extended version of %0, it can be used anywhere
$uNN
update property NN
this command forces execution of property sequence
$f
marker of the end of hardware command
$zR
regR = index of the currently selected photo or video configuration
index corresponds to seq_ss_config_* and seq_vf_config_*. this command helps to determine in which mode (photo or video) and resolution the camera is
$wR
write value from register R to hardware send/get command
this command can be used only as a portion of hardware command!
$hR IO M NNNN
wait for event trigger on camera application I/O port. check the state every M miliseconds, max waiting time for trigger change is NNNN miliseconds. the result of waiting will go to register R (value 0 = no event occured)
events are used in all Sony cameras to ensure correct interoperability of code and the camera (correct order of execution of hardware commands)
$rR ABC...
soon...
other things
there's something interesting in seq_set_prop_* and it's worth to mention. you can use this sequence in two forms, for example:
seq_set_prop_8_0 = ...; // variant 0 (for example Effect none)
seq_set_prop_8_1 = ...; // variant 1 (for example Effect solarization)
seq_set_prop_8_2 = ...; // variant 2 (for example Effect black & white)
seq_set_prop_8 = ...; // all variants in one sequence
both forms are correct. which and when to use? it's not really important but if you have a lot of common code in every single variant and only very small parts of code are depending on the number of variant then 2nd form (all in one) can be better solution. for example:
seq_set_prop_8_0 = ... #MACRO(00);
seq_set_prop_8_1 = ... #MACRO(01);
seq_set_prop_8_2 = ... #MACRO(02);
seq_set_prop_8 = ... #MACRO(%0); // use index of property variant as parameter for macro
seq_set_prop_8 = ...
$s0 %0 // r0 = index of property variant
$c0 00 #MACRO(00) $cl // if r0 = 00
$c0 01 #MACRO(01) $cl // else if r0 = 01
$c0 02 #MACRO(02) // else if r0 = 02
$cx $cx $cx;
if you are in body of seq_set_prop_* then you can use a special character %0
it returns index of current variant of property. this character is really important, despite the fact that this does not seem to be. thanks to %0 you will know, for example, what White Balance is selected, what Effect, JPEG quality and many more. you should also pay attention od command $pR NN
looping statement is used to execute the same set of code a specified number of times. looping is possible only on K800 and newer phones
$s0 01 // r0 = 01 (otherwise the loop won't even start)
[ 0 NN // loop NN times or quit looping when r0 = 0 (use $s0 00 to break the loop)
...
]
table of K800 hardware registers and syntax of Sony hardware commands:
http://www.4shared.com/file/76994820/a1b72982/K800_registers.html
table of K750, W800 and W810 hardware registers:
http://tinyurl.com/8c75bl
driver syntax checker tool for PC:
http://www.4shared.com/file/7[....]2/CamdrvSyntaxChecker_v10.html
[ This Message was edited by: Raiderski on 2009-01-03 10:42 ] |
|
tranced Joined: Jan 19, 2006 Posts: > 500 From: Santo Domingo, wonDeRland PM |
waiting then
|
idumbakumar Joined: Oct 01, 2007 Posts: > 500 From: chennai,india. PM |
Waiting.....
Thanks buddy. |
Coquito Joined: Mar 28, 2007 Posts: > 500 From: Moca, Rep.Dom PM, WWW
|
Waiting here too...
|
jigonx Joined: Oct 16, 2007 Posts: 327 PM |
Nice...!
waiting too  |
groovepeppy Joined: Dec 05, 2007 Posts: > 500 From: Parijs van Java, Indonesia PM |
Waiting too...
Black Sensation Z710e - Black Apollo 9360 |
yea g Joined: Jul 02, 2008 Posts: > 500 From: New Zealand PM, WWW
|
Nice idea! Might be able to see how much I can improve c905
|
patrak Joined: Apr 14, 2006 Posts: 15 From: Marseille, France PM |
Great!
Looking forward...
Thx |
razec Joined: Aug 20, 2006 Posts: > 500 From: Mars PM |
Great idea!
10 years at Esato |
Logicbloke Joined: Dec 15, 2008 Posts: 40 PM, WWW
|
Waiting....
This message was posted from a SGH-C180 |
mauquit Joined: Apr 05, 2008 Posts: 116 From: India PM, WWW
|
I m 2 |
nnr3 Joined: Mar 23, 2008 Posts: 357 From: Philippines PM, WWW
|
This is great!
Looking forward...
_________________
K850i[R1FA035]modded camdriver- strong 1.1
Winner of The Official Monthly Esato Camera Phone Shootout: December Edition ( 2008 )
[ This Message was edited by: nnr3 on 2009-01-03 17:16 ] |
Goldmen Joined: Oct 07, 2007 Posts: > 500 From: Bulgaria PM, WWW
|
Raiderski
Thank you for lesson 1!
It seems there is a lot to learn...
|
takev_k850i Joined: Dec 01, 2008 Posts: 55 From: Sofia,Bulgaria PM |
Well done pal,but i think that this is not very common for usual users like me for example
Sony-Ericsson "Lozenec" modding team  |
Luhccas-U1a Joined: Mar 24, 2008 Posts: > 500 PM, WWW
|
Another interesting thing would show all SET_REG's and COM_EVENT's with respective functions. |
|
Access the forum with a mobile phone via esato.mobi
|