Hello to all,
I'm opening this new topic in order to make some documentation about the cypress trackpad kext I made and about the cypress PS2 protocol itself.
This will help people understand my code and also help them if they want to customize it or just understand it a little bit more.
It might also help other devs that would like to implement other trackpads ^^, i really think that any C/C++ coder that have an unsupported trackpad can nowadays create a driver for it "easily" (of course some hard work and research to do, but doable ^^' ), i never coded a kext and never coded on PS2 protocol before this first one.
Will try to update this topic each time something revelant comes to my mind.
here is some good links to know how "standard" protocol works :
Cypress Protocol Part:
First lets speak about the cypress protocol: searching on the net, reading linux driver source code and asking some infos to cypress gave me some knowledge on how protocol works :
- like any other PS2 mouse, the cypress one uses standard values for configuring rates/resolution/data mode.
- the only difference to set the trackpad from "standard" protocol to "cypress" packet reporting seems only to rely on the firmware asking. sending the right byte to ask the firmware and then reading the bytes like in linux allowed to "activate" the cypress mode packet reporting.
- so firstly, i re-implemented the same functions present in linux source code for init. (well almost the same, some implicit configuration is done by some linux syscalls).
- once configured properly : init sequence similar to linux one (ask the trackpad its firmware, set rate and res. this can be seen on the function setTouchpadModeByte on my sourcecode), I just send one byte to set data reporting on (0xF4: meaning that from that moment, the mouse will automatically send packets for each events happening on the pad).
From there, trackpad will flood the host system with the following :
- each packet is composed of 5 or 8 bytes, depending on the header byte (first one)
- on the contrary of other trackpads (like ALPS or Synaptics), THERE IS NO ACCURATE way (no way to be 100% sure) to determine if a byte is a header byte or not : there is no bit sequence to determine that a byte is header or a byte squence separator between packets to tell that new packet is coming
- The only way to deal with this is to count correctly each received bytes. and try to "validate" a possible header byte by checking consistency (example: if tap bit is on, left or right bit should be on, etc ...)
- And in case of invalid header byte, empty actual buffer and ask trackpad a resend of last packet (send 0xFE).
- the parsing of the packet content was also given by re-implementing the cypress linux source code.
- for now, have found 2 scenarios in that the trackpad sends 8 bytes packet instead of 5 : on init, and when two fingers are on the trackpad (sending 2 distinct coordinates).
- for 1/3/4/5 fingers, it only sends 5 bytes : specifying on the header the number of fingers but followed only with one finger coordinate.
- so, for a single move on the pad, the trackpad, floods the host with packets containing coordinates.
- once finger/s leave the pad, 500 null bytes (if none is lost) is sent to the host. (don't ask me why)
Source code implementation part:
So why have i based my code on VoodooPS2Controller, and more exactly on rehabman's one ?
Because it is a already existing kext that uses and implements ApplePS2Controller (which allows PS2 init/send/receive), and also because it is clean and easy to add new hardware implementation : just added 2 new files at beginning (VoodooPS2CypressTouchPad.cpp and VoodooPS2CypressTouchPad.h) with new class and object instanciation base on the already present classes.
Then implemented cypress init/protocol handling on it.
One thing I have done to manage correctly mouse movement is storing infos about "frames" : each finger move on the trackpad is considered as a packet frame, I store the timer when the frame begins and count packets, if fingers leave pad i clear the counters, if a change on the number of fingers appears (new fingers/removed fingers) I consider it as a new frame.
For now that is the only infos that comes to my mind, if somes are working on a PS2 driver, or have questions regarding my code, don't hesitate, ask it here, i will answer and update this post if revelant.
Hope that it would help other PS2 devs beginners.