[ nem96 @ 15.11.2010. 16:28 ] @
Ovaj programski jezik je nepravedno odbacen. Zbog toga je puno problema kada je potrebno naci odgovarajucu biblioteku. Meni je licno potrebna ps/2 biblioteka za misa. Nasao sam slicnu biblioteku na forumu mikroelektronike, ali je za mikropascal for pic imesto za avr. Treba mi pomoc. Kako prepraviti biblioteku. ona u sebi ne sadrzi nikakve portove pa ne bih mogao da ivrsim "pinning". evo koda: Code: unit PS2_Mouse; {interface } type TMouseData = record Keys: byte; DeltaX: integer; DeltaY: integer; DeltaZ: integer; // Scrollwheel end; function Ps2_Mouse_Init: boolean; // Initializes the Mouse Ps2 library and resets the mouse. // Returns true if a "Mouse selftest passed" code is received from the Mouse, else false. // Also enables the ScrollWheel (if any present). function Ps2_Mouse_ReadData(var MouseData: TMouseData): boolean; // Reads the PS2 mouse data into "MouseData". // MouseData.Keys returns the pressed keys (one bit for every key) // MouseData.DeltaX returns the delta of the X value (hor position) with respect to the previous data // MouseData.DeltaY returns the delta of the Y value (vert position) with respect to the previous data // MouseData.DeltaZ returns the delta of the Scrollwheel value with respect to the previous data procedure Ps2_Mouse_Write(var Values: array[2] of byte; Count: byte); // Writes "Count" bytes out of "Values" to the PS2 Mouse. No reply expected here. // The list of valid commands can be found in: http://www.computer-engineering.org/ps2mouse/ procedure Ps2_Mouse_Write_Read(var Command: array[5] of byte; CountWrite: byte; var Reply: array[4] of byte; CountRead: byte); // Same as "Ps2_Mouse_Write" above, but after the write operation "CountRead" bytes are read from the mouse into "Reply". function Ps2_Mouse_Reset: boolean; // Resets the Mouse and waits (with a timeout of 2 seconds) for the "selftest passed" acknowledge. // Returns true if the "selftest passed" was acknowledged by the Mouse, otherwise false. // Remark: the Mouse also resets itself (and does a selftest) at power up time (see "Ps2_Mouse_Init"). function Ps2_Mouse_ScrollWheel_Present: boolean; // Returns true if the mouse has a scrollwheel, else false. implementation var PS2_Data_Mouse : sbit; sfr; external; PS2_Clock_Mouse : sbit; sfr; external; PS2_Data_Direction_Mouse : sbit; sfr; external; PS2_Clock_Direction_Mouse : sbit; sfr; external; TimeOut: word; TimeOut2: word; TimeOutError: boolean; ScrollWheel: boolean; function WaitForClockLow: boolean; // returns true if the clock went low within the TimeOut var TmpW: word; begin TmpW := 0; repeat inc(TmpW); until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut); Result := (PS2_Clock_Mouse = 0); end; function WaitForClockHigh: boolean; // returns true if the clock went high within the TimeOut var TmpW: word; begin TmpW := 0; repeat inc(TmpW); until (PS2_Clock_Mouse = 1) or (TmpW >= TimeOut); Result := (PS2_Clock_Mouse = 1); end; function WaitForInitialClockLow: boolean; // long timeout var TmpW: word; begin TmpW := 0; repeat inc(TmpW); until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut2); Result := (PS2_Clock_Mouse = 0); end; function Ps2_Mouse_Get_Byte: byte; // Reads one byte from the PS2 Mouse var I, Tmp: byte; begin TimeOutError := false; if not WaitForInitialClockLow then begin TimeOutError := true; exit; // wait for first clockpulse with long timeout end; I := 0; Tmp := 0; while I < 11 do // 11 clockpulses expected begin if not WaitForClockLow then // wait for clock low (start of clockpulse) begin TimeOutError := true; exit; end; if (I > 0) and (I < 9) then begin Tmp := Tmp Shr 1; Tmp.7 := PS2_Data_Mouse; end; if not WaitForClockHigh then // wait for clock high (end of clockpulse) begin TimeOutError := true; exit; end; inc(I); end; Result := tmp; end; function PS2_Mouse_SelftestResult: boolean; var Tmp: byte; Cnt: word; begin Result := false; // wait for selftest completion Cnt := 0; repeat PS2_Clock_Mouse := 1; PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send) nop; nop; Tmp := Ps2_Mouse_Get_Byte; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock (do not allow Mouse to send) nop; nop; if not TimeOutError then // actual code received begin if Tmp = $AA then Result := true // reset completion code (selftest done) else if Tmp = $FC then exit; // error end; inc(Cnt); until (Result = true) or (Cnt > 66); // 66 times 30 msecs is approx 2 secs repeat // purge any extra bytes sent PS2_Clock_Mouse := 1; PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send) nop; nop; tmp := Ps2_Mouse_Get_Byte; until TimeOutError; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock (do not allow Mouse to send) nop; nop; end; function Ps2_Mouse_Enable_ScrollWheel: boolean; var Cmd: array[7] of byte; Tmp: byte; begin Result := false; Cmd[0] := $F3; // Set Sample rate command Cmd[1] := 200; // 200 Cmd[2] := $F3; Cmd[3] := 100; // 100 Cmd[4] := $F3; Cmd[5] := 80; // 80 Cmd[6] := $F2; // get ID byte Ps2_Mouse_Write(Cmd, 7); PS2_Clock_Mouse := 1; PS2_Clock_Direction_Mouse := 1; nop; nop; Tmp := Ps2_Mouse_Get_Byte; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; nop; nop; Result := (not TimeOutError) and (Tmp = 3); end; function Ps2_Mouse_ScrollWheel_Present: boolean; begin Result := ScrollWheel; end; function Ps2_Mouse_Reset: boolean; var Arr: array[1] of byte; begin TimeOutError := false; ScrollWheel := false; Result := false; Arr[0] := $FF; // reset command Ps2_Mouse_Write(Arr, 1); Result := PS2_Mouse_SelftestResult; ScrollWheel := Ps2_Mouse_Enable_ScrollWheel; Arr[0] := $F4; Ps2_Mouse_Write(Arr, 1); // Enable Data Reporting PS2_Clock_Mouse := 0; // force clock low (prevent mouse from sending data) PS2_Clock_Direction_Mouse := 0; nop; nop; // prevent read after write problem end; function Ps2_Mouse_Init: boolean; // Initializes the Mouse Ps2 routines begin TimeOutError := false; Result := false; ScrollWheel := false; TimeOut := DWord(11 * Clock_MHz); // gives approx 1 ms of timeout TimeOut2 := 30 * TimeOut; // approx 30 ms PS2_Clock_Mouse := 0; // force clock low PS2_Clock_Direction_Mouse := 0; nop; nop; // prevent read after write problem PS2_Data_Mouse := 1; PS2_Data_Direction_Mouse := 1; nop; nop; Result := PS2_Mouse_SelftestResult; Result := Ps2_Mouse_Reset; // give extra reset end; function Ps2_Mouse_ReadData(var MouseData: TMouseData): boolean; // Reads 3 or 4 bytes from the Ps2 Mouse into "MouseData" var Index, Tmp: byte; TmpCodes: array[4] of byte; MaxCount: byte; begin Result := false; TimeOutError := false; Memset(@TmpCodes, 0, SizeOf(TmpCodes)); PS2_Clock_Mouse := 1; PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send) nop; nop; // wait for first low clock with (short) timeout (low clock does not occur when no key is pressed: nothing to send) if not WaitForClockLow then begin PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock nop; nop; exit; // no new data end; MaxCount := 3; if ScrollWheel then MaxCount := 4; Index := 0; Repeat // get bytes until all bytes read Tmp := Ps2_Mouse_Get_Byte; if TimeOutError then begin PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock nop; nop; exit; // Read Error end; TmpCodes[Index] := Tmp; inc(Index); until Index = MaxCount; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock (prevent Mouse to send) nop; nop; MouseData.Keys := TmpCodes[0] and 7; MouseData.DeltaX := 0; if TmpCodes[0].4 = 1 then // X "sign" bit MouseData.DeltaX := -1; lo(MouseData.DeltaX) := TmpCodes[1]; MouseData.DeltaY := 0; if TmpCodes[0].5 = 1 then // Y "sign" bit MouseData.DeltaY := -1; lo(MouseData.DeltaY) := TmpCodes[2]; MouseData.DeltaZ := 0; if TmpCodes[3].7 = 1 then MouseData.DeltaZ := -1; lo(MouseData.DeltaZ) := TmpCodes[3]; Result := true; end; function WaitForClockHighThenLow: boolean; var TmpW: word; begin TmpW := 0; repeat inc(TmpW); until (PS2_Clock_Mouse = 1) or (TmpW >= TimeOut); Result := (PS2_Clock_Mouse = 1); if not result then Exit; TmpW := 0; repeat inc(TmpW); until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut); Result := (PS2_Clock_Mouse = 0); end; function WaitForDataLowThenHigh: boolean; var TmpW: word; begin TmpW := 0; repeat inc(TmpW); until (PS2_Data_Mouse = 0) or (TmpW >= TimeOut); Result := (PS2_Data_Mouse = 0); if not result then Exit; TmpW := 0; repeat inc(TmpW); until (PS2_Data_Mouse = 1) or (TmpW >= TimeOut); Result := (PS2_Data_Mouse = 1); end; procedure Ps2_Mouse_Write_Byte(Value: byte); // writes 1 byte to the PS2 Mouse (command or data) var parity, I: byte; label ExitWriteByte; begin TimeOutError := false; // calculate parity Parity := 0; for I := 0 to 7 do if Value.I = 0 then inc(Parity); if Parity.0 = 1 // odd then Parity := 0 else Parity := 1; // make a request to send condition PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock delay_us(200); PS2_Data_Mouse := 0; PS2_Data_Direction_Mouse := 0; // Make data line zero nop; nop; PS2_Clock_Direction_Mouse := 1; PS2_Clock_Mouse := 1; // release clock line nop; nop; if not WaitForInitialClockLow then begin TimeOutError := true; goto ExitWriteByte; end; // send data and parity for I := 0 to 8 do begin if I < 8 then begin PS2_Data_Mouse := Value.0; // send LSB bit Value := Value shr 1; // get next bit end else PS2_Data_Mouse := Parity; // send parity if not WaitForClockHighThenLow then begin TimeOutError := true; goto ExitWriteByte; end; end; PS2_Data_Mouse := 1; PS2_Data_Direction_Mouse := 1; // release dataline if not WaitForClockHighThenLow then begin TimeOutError := true; goto ExitWriteByte; end; if not WaitForDataLowThenHigh then // Check acknowledge (data line) begin TimeOutError := true; goto ExitWriteByte; end; ExitWriteByte: // done, release data and clock PS2_Data_Direction_Mouse := 1; PS2_Data_Mouse := 1; PS2_Clock_Direction_Mouse := 1; PS2_Clock_Mouse := 1; end; procedure Ps2_Mouse_Write(var Values: array[2] of byte; Count: byte); // Writes "Count" bytes out of "Values" to the PS2 Mouse. var Index, Reply: byte; begin Index := 0; while Count > 0 do begin Ps2_Mouse_Write_Byte(Values[Index]); // send byte to the Mouse if TimeOutError then break; Reply := Ps2_Mouse_Get_Byte; // get the reply ($FA is Ok) if TimeOutError then break; inc(Index); dec(Count); end; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // block clock nop; nop; PS2_Data_Direction_Mouse := 1; PS2_Data_Mouse := 1; // release data line nop; nop; end; procedure Ps2_Mouse_Write_Read(var Command: array[5] of byte; CountWrite: byte; var Reply: array[4] of byte; CountRead: byte); var I: byte; begin Ps2_Mouse_Write(Command, CountWrite); if CountRead > 0 then begin I := 0; PS2_Clock_Mouse := 1; PS2_Clock_Direction_Mouse := 1; // enable the mouse to send nop; nop; while I < CountRead do begin Reply[I] := Ps2_Mouse_Get_Byte; inc(I); end; PS2_Clock_Mouse := 0; PS2_Clock_Direction_Mouse := 0; // disable the mouse to send nop; nop; end; end; end. |