hi
i hab jetzt wieder zeit zum schreiben. ps2 ist gemeint damit du nicht die quadratursignale aus der maus nehmen musst sondern direkt die daten geschickt bekommst.
zu dem ganzen code gibs auch einen originalautor nur der muss mir bitte verzeihen weil ich finde ihn nicht auf die schnelle.
ps2.c
Code:
/***************************************************************************
* Copyright (C) 2008 by Thomas Gruebler and CRCT *
* thomas a t gruebler d o t at *
* www.crct-robots.eu *
***************************************************************************/
#include "ps2.h"
unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 10ms auf CLCK=LO warten
{
unsigned int ms = 1100;
while ((ms--)!=0)
{ // wenn der Timer läuft
if (!PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_ms(0.01);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}
unsigned char ps2_wait_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 50µs auf CLCK=LO warten
{
unsigned int us = 50000; // Timer 0 Preload 50µs
while ((us--)!=0)
{ // wenn der Timer läuft
if (!PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_us(.001);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}
unsigned char ps2_wait_for_clck_hi (unsigned char clkpin) // PS/2: Bis zu 50µs auf CLCK=HI warten
{
unsigned int us = 50000; // Timer 0 Preload 50µs
while ((us--)!=0)
{ // wenn der Timer läuft
if (PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_us(.001);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}
unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin)
{
unsigned char i = -1;
unsigned char pb = 0;
PS2_CLCK_LO; // setze CLCK LO
delay_us(100); // warte 100µs
PS2_DATA_LO; // setze CLCK LO, DATA LO
delay_us(25); // warte 25µs
PS2_CLCK_HI; // setze CLCK HI, DATA LO
if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_send_error; // 10ms auf fallende Flanke (CLCK) warten
for (i=0; i<8; i++)
{ // Datenbits LSB->MSB
if (val & 0x01)
{ // Bit ist 1
pb++; // Parityzähler erhöhen
PS2_DATA_HI; // Datenleitung HI sezen
}
else
{ // Bit ist 0
PS2_DATA_LO; // Datenleitung LO setzen
}
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten
val = val >> 1;
}
if (pb & 0x01) // PB ungerade?
PS2_DATA_LO; // -> kein Parity Bit
else // PB gerade?
PS2_DATA_HI; // -> Parity Bit
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten
i++;
PS2_DATA_HI; // CLCK und DATA freigeben
PS2_CLCK_HI; // CLCK und DATA freigeben
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (0); // Fehlerfrei
ps2_send_error: // Fehlerhandling
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (i); // Fehlernummer zurückgeben
}
unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin)
{
unsigned char i;
bytes_read = 0; // Anzahl gelesener Zeichen
PS2_CLCK_HI; // CLCK freigeben
while (bytes_read < len)
{
buffer[bytes_read] = 0;
for (i=1; i<=11; i++)
{
if (i==1) //beim Startbit
{ if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_read_error; } //10ms auf fallende Flanke (CLCK) warten
else //sonst
{ if (ps2_wait_for_clck_lo(clkpin)) goto ps2_read_error; } //50µs auf fallende Flanke (CLCK) warten
if (i>=2 && i<=9)
{ // wenn Datenbit
if (PS2_DATA_IS_HI) // HI
buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x80;
else // LO
buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x00;
}
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_read_error; // 50µs auf steigende Flanke (CLCK) warten
}
bytes_read++; // Bytezähler erhöhen
}
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (0); // Fehlerfrei
ps2_read_error: // Fehlerhandling
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (i); // Fehlernummer zurückgeben
}
void fatal_error (unsigned char errcode, unsigned int addinfo)
{
// Fehlerbehandlung hier rein....
LEDP ^= (1<<LED3); //Led3 toggeln
// while (1) {}
}
void maus_init(unsigned char clkpin, unsigned char datapin)
{
unsigned char c=0,i=0; // Hilfsvariablen
if (ps2_send(0xFF, MOUSE)) fatal_error(0x01,0x00); // PS/2 Cmd: Reset
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x02,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x03,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x04,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xAA) fatal_error(0x05,c); // auf BAT-Quittung ($AA) prüfen
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x06,0x00); // auf Lesefehler von PS/2 prüfen (Device ID überspringen)
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xF3, MOUSE)) fatal_error(0x17,0x00); // PS/2 Cmd: Set Sample Rate
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x18,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x19,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(200, MOUSE)) fatal_error(0x1A,0x00); // 200 Samples per second
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x1B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x1C,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xE8,MOUSE)) fatal_error(0x07,0x00); // PS/2 Cmd: Set Resolution
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x08,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x09,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0x03, MOUSE)) fatal_error(0x0A,0x00); // Resolution 2 = 4 counts/mm = 2 Impulse pro Zahn
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xF0, MOUSE)) fatal_error(0x0D,0x00); // PS/2 Remote Mode einschalten
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0E,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0F,c); // auf Quittung (ACK/$FA) prüfen
}
ps2.h
Code:
/***************************************************************************
* Copyright (C) 2008 by Thomas Gruebler and CRCT *
* thomas a t gruebler d o t at *
* www.crct-robots.eu *
*
* Belegung Stecker in der Maus
* Gruen | Weis | Rot | 2x Schwarz
* Clock Data VCC GND
***************************************************************************/
#ifndef PS2_H
#define PS2_H
#include "global.h"
#include "main.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
unsigned char head;
char rwheel;
char lwheel;
} ps2_movement_type;
// #define PS2_CLCK_IS_HI (PINC & (1<<PC1))
// #define PS2_DATA_IS_HI (PINC & (1<<PC0))
// #define PS2_CLCK_LO DDRC |= (1<<PC1)
// #define PS2_CLCK_HI DDRC &= ~(1<<PC1)
// #define PS2_DATA_LO DDRC |= (1<<PC0)
// #define PS2_DATA_HI DDRC &= ~(1<<PC0)
#define PS2_CLCK_IS_HI (PINC & (1<<clkpin))
#define PS2_DATA_IS_HI (PINC & (1<<datapin))
#define PS2_CLCK_LO DDRC |= (1<<clkpin)
#define PS2_CLCK_HI DDRC &= ~(1<<clkpin)
#define PS2_DATA_LO DDRC |= (1<<datapin)
#define PS2_DATA_HI DDRC &= ~(1<<datapin)
#define MOUSE1 PC1, PC0
#define MOUSE2 PC3, PC2
#define MOUSE clkpin, datapin
unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_hi (unsigned char clkpin);
unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin);
unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin);
void fatal_error (unsigned char errcode, unsigned int addinfo);
void maus_init(unsigned char clkpin, unsigned char datapin);
#endif
beispiel für den auslesecode:
Code:
char xl = 0;
char yl = 0;
char xr = 0;
char yr = 0;
unsigned char c=0,i=0; // Hilfsvariablen
ps2_movement_type moved; // Bewegungsmeldung
//PS/2 Daten auslesen++++++++++++++++++
if (ps2_send(0xEB, MOUSE1)) fatal_error(0x0A,0x00); // READ DATA Command
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE1)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c);
if (!ps2_read((unsigned char*)&moved,3,c, MOUSE1))
{
//Maus1 daten auslesen
yl =(char)moved.lwheel;
xl =(char)moved.rwheel;
}
if (ps2_send(0xEB, MOUSE2)) fatal_error(0x0A,0x00); // READ DATA Command
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE2)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c);
if (!ps2_read((unsigned char*)&moved,3,c, MOUSE2))
{
//Maus2 daten auslesen
yr =(char)moved.lwheel;
xr =(char)moved.rwheel;
}
mein code ist gegenüber zum original so das man 2 mäuse ansteuern kann und keine timer braucht.
für richtigkeit und funktion übernehme ich natürlich keine haftung. ging bei mir aber ganz gut
lg
Lesezeichen