PS/2 Mouse Input via SPI, I2C, Interrupts? TVOut +

Guys, I'm doing some tests with the PS/2 Mouse Interface using the url below, which works great. But, if I use the TVOut, it blocks the entire code, as TVOut is interrupt (Timer1) based, while the PS/2 lib below is just bit-banging.

http://www.arduino.cc/playground/ComponentLib/Ps2mouse

I also tested another PS2 Mouse lib, same thing, bit-banging.

So, has anyone done another way to read PS/2 Mouse Input while keeping the TVOut working?

If no one has done, I will do it, just trying to save some time. :wink:

Thanks, Wk

Here's the detailed info on the PS/2 protocol:

http://www.computer-engineering.org/ps2protocol/

Not sure if SPI or I2C can handle this.

Wk

Interesting: http://sra.vjti.info/knowledgebase/tutorials/interfacingkeyboard

Looks like I'm near... :wink:

Wk

Ok, here's the PS2 code with Interrupts. It works with the Serial Output. But as soon as I turn TVOut it stops working since the TVOut interrupts messes up the other interrupts timing.

#include <TVout.h>
#include <fontALL.h>

#define SERIALOUT 1 // 38400 bauds
#define TV_OUT 0

#define ps2data 5 // can be any pin
#define ps2clk 2  // must be in the Interrupt pin 2 which is interrupt 0

TVout TV;
char mstat, mx, my = 0;

// =============================================== SETUP ============================================== //

void setup()
{    
  #if SERIALOUT
    Serial.begin(38400);
  #endif
  
  gohi(ps2clk);
  gohi(ps2data);
  ps2Write(0xff);  // reset
  ps2Read();  // ack byte
  ps2Read();  // blank */
  ps2Read();  // blank */
  ps2Write(0xf0);  // remote mode
  ps2Read();  // ack
  delayMicroseconds(100);
  
  #if TV_OUT
    TV.begin(_NTSC,184,72);
    TV.select_font(font6x8);
    TV.println("Testing Mouse:");  
  #endif
}

// =============================================== LOOP =============================================== //

void loop()
{    
  // Read Mouse Values //
  ps2Write(0xeb); ps2Read(); mstat = ps2Read(); mx = ps2Read(); my = ps2Read();
    
  #if TV_OUT
    TV.set_cursor(0,0);
    TV.print(mx, DEC);  TV.print(" ");  TV.print(my, DEC); TV.println("         ");
  #endif

  #if SERIALOUT
    Serial.print(mx, DEC);  Serial.print(" ");  Serial.println(my, DEC);
  #endif  
      
  delay(10);
}

// =============================================== PS/2 INTERFACE ===================================== //

void gohi(int pin) { pinMode(pin, INPUT); digitalWrite(pin, HIGH); }
void golo(int pin) { pinMode(pin, OUTPUT); digitalWrite(pin, LOW); }

volatile unsigned char tempData = 0;
volatile unsigned char parity = 1;
volatile boolean completed = false;
volatile char psclk = -1;
volatile unsigned char bit = 0x01;

// =============================================== WRITE ============================================== //

void ps2Write(unsigned char data)
{        
	unsigned char i;
	parity = 1;
	
	gohi(ps2data);
	gohi(ps2clk);
	delayMicroseconds(300);
	golo(ps2clk);
	delayMicroseconds(300);
	golo(ps2data);
	delayMicroseconds(10);
        tempData = data;
        completed = false;
        psclk = -1;
        attachInterrupt(0, ps2ClockWriteInterrupt, FALLING); // Pin 2
	gohi(ps2clk);	// start bit // wait for device to take control of clock
        while (!completed) { ; }
}

void ps2ClockWriteInterrupt()
{  
  switch (psclk)
  {
    case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 8 bit Data
	if (tempData & 0x01) gohi(ps2data); else golo(ps2data);
        parity = parity ^ (tempData & 0x01);
        tempData = tempData >> 1;
        break;
        
    case 8: // PARITY Bit
      if (parity) gohi(ps2data); else golo(ps2data);
      break;
            
    case 9: // STOP Bit
      gohi(ps2data);
      attachInterrupt(0, ps2ClockWriteInterrupt, HIGH); // Pin 2
      break;
      
    case 10:
      detachInterrupt(0); // Pin 2
      golo(ps2clk); // hold up incoming data
      completed = true;      
      break;
  }
 
  psclk++;
}


// =============================================== READ =============================================== //

unsigned char ps2Read()
{        
	unsigned char i;
	parity = 1;
	
        tempData = 0x00;
        completed = false;
        bit = 0x01;
        psclk = -1;
        attachInterrupt(0, ps2ClockReadInterrupt, FALLING); // Pin 2
	gohi(ps2data);
	gohi(ps2clk);        
        while (!completed) { ; }
        
        return tempData;
}

void ps2ClockReadInterrupt()
{  
  switch (psclk)
  {
    case 0: // Start bit //
      break;
      
    case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: // 8 bit Data
      if (digitalRead(ps2data) == HIGH) tempData = tempData | bit;
      bit = bit << 1;
      break;
        
    case 9: // PARITY Bit
      break;
            
    case 10: // STOP Bit
      attachInterrupt(0, ps2ClockReadInterrupt, HIGH); // Pin 2
      break;
    
    case 11:
      detachInterrupt(0); // Pin 2
      golo(ps2clk); // hold up incoming data
      completed = true;      
      break;
  }
 
  psclk++;
}

Ok, I'm out of ideas now... :frowning:

Wk

hello there :slight_smile:
i have some quiz, i dont understand a few instructions from the above code, of PS2 mouse

from the function:

void ps2ClockWriteInterrupt()
what do these instructions do?:
parity = parity ^ (tempData & 0x01);
tempData = tempData >> 1;

why do these variables are initiated at these values:
bit = 0x01;
tempData = 0x00;

from the function:

void ps2ClockReadInterrupt()

what do these instructions do?:
tempData = tempData | bit;
bit = bit << 1;

and the last question:

what is the role of ";", a know it is a null statement but does exactly does?

while (!completed) { ; }

Arduino - Home

has all the information you need to know about the bitwise operators, including which they are.

what is the role of ";", a know it is a null statement but does exactly does?

The ; is an end of statement marker. When used by itself, it is a very short statement, and is not required.

while (!completed) {}
does exactly the same thing, but looks like a mistake. The ; in the braces makes it clear that the function is explicitly doing nothing while completed is not true. (Presumably, something else must be changing the value in completed, or the while loop would never end.)