Adding PS/2 mouse to my FPGA computer
This is a followup of my original post.
So far I had PS/keyboard only on my FPGA computer. The time has come to add the mouse, too. Without any investigation how PS/2 mouse works, I first tried to plug the mouse into my PS/2 keyboard connector and watch what would come from it. It didn't work. The keyboard worked, but the mouse didn't. I expected that the mouse would send bytes as I move or click, but it didn't. After a brief investigation, I found out that the PS/2 mouse needs an initialization in order to start sending bytes to the computer.
PS/2 is actually a bidirectional interface. Both computer and mouse/keyboard can send bytes to the other. Well, the initialization sequence for the mouse actually means that the computer needs to send one byte to the mouse. Unfortunately, that is not so simple. In order to send a command to the mouse, host (computer) needs to set both data and clock lines low for a given period of time, then to release both lines, and then to start setting bits of the command in synchronization with the clock that has just started to arrive from the mouse.
Fortunately, there is a module that already does all these steps, and can be found here.
I have replaced my original PS2 module with this one and now I have two ports in my computer:
The default value for the INITIALIZE_MOUSE parameter is 1, so the mouse controller initializes the mouse at reset.
I have allocated another IRQ for the mouse:
In the main irq loop, the mouse actually triggers the CPU interrupt #5:
When the CPU detects that some bit in the irq register is set to 1, it triggers the interrupt handler routine. It does that by first checking if the interrupt vector is not zero. After that, the CPU pushes the current PC register and flags to the stack and then jumps to the interrupt handling routine.
The mouse interrupt routine receives three bytes from the PS/2 mouse:
Three bytes for each mouse event come one by one. When all three bytes arrive, we are ready to process them in the main program:
The first byte gives the button status: which button has been pressed. The second byte gives the x-axis speed of movement, or the amount of pixels the mouse has moved, while the third byte does the same, just for the y-axis. Both second and third byte are 8-bit signed values, meaning that if you read a value greater than 127, the value is negative (and can be calculated by subtracting it from the 256).
The whole demo can be seen here:
Conclusion
Adding PS/2 mouse was not that complicated once I managed to find the proper Verilog controller. After that, it was just the matter of allocating one more interrupt and writing handlers for it.
Comments
Comments powered by Disqus