Page 1 of 26

Lens serial communication

PostPosted: Thu Oct 31, 2013 12:12 am
by lain
This is something I have been playing with as well, since I am working on a camera design and would like to use Nikon lenses with it even though their aperture control is still mechanical.

At present I'm working on gathering more information about the lens protocol itself by gathering lots of data. I'm just improving my data capture setup, moving from sniffing the lines at the D5100 mainboard to tapping into the lines in a macro extension tube with AF support. Using the extension tube means I can sniff an unmodified camera and lens, so I can also test on my D800.

Some patents mentioned in another topic on the forum gave a great starting point and explained the signalling used.

It is a 3 wire, 5V protocol with signals H/S (meaning handshake, also called R/W and In/Out), Data, and SCLK (Clock). SPI is used with SO and SI tied together to form Data, and then when one side expects to receive data it leaves SO in Hi-Z state so it does not interfere with the sender's serial output.

Looking into the camera body with the camera upright, the pins are lettered A thru H (or 1 thru 8 as is used on the wiki). B is H/S, C is SCLK, D is Data.
Also I believe E and H are motor drive signals, 90 degrees out phase to determine direction. These are used for AF based on my testing, but I need to scope them a bit more to be 100% certain what's going on, but repair manuals and whatnot strongly suggest that is the case.

Series resistors are used in case there is a conflict where both sides transmit, which seems possible with some new changes to the protocol -- old patents say a lens shall send byte 0xFF in response to unknown commands, but some newer commands have data phase going from camera to lens. In such cases, the camera and lens may attempt to transmit simultaneously, so series resistors prevent overcurrent on the output pins when one is high and the other is low.

The clock line is always driven by the body and it idles high. It operates at 142kHz or very close to that.
Data transitions on the falling clock edge, valid on the rising edge.
The handshake line is open-collector, pulled high by resistor.

There is a "power-down" state where no communication takes place. This state is identified by H/S high, Data and SCLK low. There seems to always be a command sent before entering this state, and a certain sequence of lines going high/low to bring the lens out of this state and back to normal communcation. This is different from the bus idling between commands, where SCLK is normally high.

Communication is always initiated by the camera body from what I have seen.
The camera pulls H/S low (I refer to this as "asserting H/S") for a fixed period of time -- I think this is about 125 microseconds, but not sure, could firmware people take a look? :pray: -- then releases H/S (it goes high). The camera then waits for H/S to go low again.
As soon as the lens sees H/S is low, it asserts H/S and keeps it asserted to indicate it's ready and waiting for a command. They can both assert H/S simultaneously because it is open-collector, so they are both just pulling it low, neither ever drive it high.
In my testing, the lens always asserts H/S before the camera releases it, so H/S remains low for the duration.

Upon seeing H/S is low after releasing it, the camera knows the lens is ready and it clocks out the command, which is one byte. Data is always sent as one byte. No single transmission is ever greater than one byte. The bus always idles between bytes.

When the lens is done with the command, it releases H/S.
If the command involves data transfer, the lens releases H/S after it knows which command it is, then asserts H/S when the data byte is in the transmit buffer ready to go (if lens -> camera), or when the buffer is empty and ready to receive the next data byte (if camera -> lens). The camera then toggles clock to send/receive one byte. Direction of transfer is determined by the command alone as best I can tell, I haven't seen any indication that a bit in the command determines direction.

If the command instructs the lens to perform an action, the lens will not be ready for another command until the action is complete. Therefore: if the command involves data, H/S will be asserted longer after the last byte while the action is performed; if the command does not involve data, then H/S is asserted longer after the initial command byte. Put another way: the lens performs the action on the last byte (which may be the command byte!) before returning to idle, and it will not release from that byte until the action is complete. This provides an easy way to discern reads from writes by timing analysis, since the lens MCUs are slow and take a relatively long time to release H/S in all cases I have seen.

Anyway, I can clean up all the above and add it to the wiki at some point with pretty pictures of data captures and so on. I've written a simple tool to parse captures from the logic analyzer into a list of all commands and their corresponding data. It works, just needs some refinement and then I plan to capture LOTS of data from many lenses and build a comprehensive listing of all commands seen and the data they have been seen with, including how many times each unique command+data combo was seen, etc.

Hopefully that data will be useful to those of you working on the firmware, and I'm hoping firmware folks can help me figure out what some of the commands mean as well :drool:

I wrote this quickly and I haven't had breakfast yet, so sorry for any errors!
Oh, interesting anecdote: one of Nikon's patents covers commands for Power Zoom, though I don't believe any Nikkor glass has such a thing? But that patent also talks about AF commands I don't think I've seen in use... I see different commands used to control AF.

Re: Lens serial communication

PostPosted: Thu Oct 31, 2013 12:25 am
by leegong
Hi , lain ,
In D5100 FirmWare , two I/O ports are used for lens communication besides serial interface.
1)PI3 , camera body always set PI3 low before it wants to send command to lens, after completes lots of setting ,
then camera set it high .
2)PJ7 , it's used to generate interrupt , upon interrupt is triggered , the interrupt handler
sends one byte to lens , so if there are many bytes to be sent to lens (one byte for command code,
several bytes for extra parameters) , PJ7 should be triggered many times .
3)each bit in commands and parameters for lens is inverted then sent to lens.
4)it seems that 0xFF (not negated)is always sent to lens before camera is going to send command byte.

Best reagrds,

Re: Lens serial communication

PostPosted: Fri Nov 01, 2013 9:21 am
by lain
Hi leegong,

It sounds like PI3 is the H/S "handshake" signal, then. PJ7 may be connected to H/S as well, I think a patent mentioned that exact arrangement actually.

When you say the bits are inverted, do you mean like logical "not," or do you mean they are bitswapped? I know the protocol sends least significant bit first.

Interesting about 0xFF, that conflicts with what I have seen, maybe it's something to do with the SPI controller that never goes out on the wire? For example, below is a screenshot of a typical command as I have seen them.

H/S is asserted by the camera for at least 125us (please confirm this value whenever you can), then released.
Then the command byte is sent out on the Data line (0x41 here), toggling SCLK for each bit of course. When the lens is ready to send or accept the next byte it asserts H/S and the camera toggles SCLK. On the last byte, the lens releases H/S when it is done processing the command.

P.S. Is it possible to upload images directly here for posting? I didn't see an option...

Re: Lens serial communication

PostPosted: Fri Nov 01, 2013 8:52 pm
by leegong

Re: Lens serial communication

PostPosted: Sun Nov 03, 2013 1:54 am
by leegong
Hey ,lain ,
The value of H/S duration in Emulator is weird , here's the debugging result that i got :
0555.458500000ms set PI3 Low (@0xBFC43DEC)
0555.462025000ms set PI3 High (@0xBFC43DE6)
0557.074515000ms set PI3 Low (@0xBFC43DEC)
0562.175130000ms set PI3 Low (@0xBFC43DEC)
0563.804280000ms set PI3 High (@0xBFC43DE6)
0565.411900000ms set PI3 Low (@0xBFC43DEC)
Is the duration important for you to sniff lens serial communication ? if not , let's solve it at later time ,
i'll summmarize the formatting of each command which is sent to lens , hoping this
will help you , for example :
command code : 0xC5 , no input parameter , 8 bytes response from lens
command code : 0xD3 , input 1 byte parameter = enum {0xC3 , 0x83}, no response from lens .

Best regards,

Re: Lens serial communication

PostPosted: Sun Nov 03, 2013 7:47 am
by coderat
Lain, can you precisely measure baud rate to lens just after plugin ?
What I see in Firmware is setting to 96 KBaud. So it is strange, may be it is 96 KBaud at the begining and then switched faster if lens can?
What lens do you use ?

P.S. do not rely on patents, only rely things you measure: a lot of things like lens commands are just different. Making a patent, doesn't necessary mean they will use it like this.


Re: Lens serial communication

PostPosted: Mon Nov 04, 2013 4:22 am
by lain

Re: Lens serial communication

PostPosted: Mon Nov 04, 2013 4:29 am
by leegong

Re: Lens serial communication

PostPosted: Mon Nov 04, 2013 4:50 am
by leegong

Re: Lens serial communication

PostPosted: Mon Nov 04, 2013 5:31 am
by lain