Skip to content

Commit

Permalink
Fixed keyboard lockup during PC cold start (when power applied)
Browse files Browse the repository at this point in the history
based on @Hamberthm fixes for esp-32. See issue #21

Hamberthm's comments:
* On my 486 PC, ACKs were being missed by the host controller during LED
set command handling. This made the process to end and the controller
to ignore the keyboard after that command. This makes it stable.

* Testing in my Toshiba 205CDS with a combined port, DEVICE ID command was
failing to write the ID properly. Added some loops to shield time to the
controller and get them properly.

* The interface was missing some commands in one of my sytems because of
waiting to send the 0xAA "BAT test success". BAT success should always
be sent a couple of houndred of milliseconds after power up,
regarding state.
  • Loading branch information
ole00 authored and Harvie committed Mar 3, 2024
1 parent 15cb56c commit 961b013
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions src/ps2dev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//Enable serial debug mode?
//#define _PS2DBG Serial

#define BYTE_INTERVAL_MICROS 100

//since for the device side we are going to be in charge of the clock,
//the two defines below are how long each _phase_ of the clock cycle is
#define CLKFULL 40
Expand Down Expand Up @@ -226,14 +228,16 @@ int PS2dev::read(unsigned char * value)

void PS2dev::keyboard_init()
{
while(write(0xAA)!=0);
delay(10);
delay(200);
write(0xAA);
return;
}

void PS2dev::ack()
{
while(write(0xFA));
delayMicroseconds(BYTE_INTERVAL_MICROS);
write(0xFA);
delayMicroseconds(BYTE_INTERVAL_MICROS);
return;
}

Expand All @@ -245,7 +249,8 @@ int PS2dev::keyboard_reply(unsigned char cmd, unsigned char *leds)
case 0xFF: //reset
ack();
//the while loop lets us wait for the host to be ready
while(write(0xAA)!=0);
while (write(0xFA)!=0) delay(1); //send ACK
while (write(0xAA) != 0) delay(1); // send BAT_SUCCESS
break;
case 0xFE: //resend
ack();
Expand All @@ -268,20 +273,25 @@ int PS2dev::keyboard_reply(unsigned char cmd, unsigned char *leds)
break;
case 0xF2: //get device id
ack();
write(0xAB);
write(0x83);
while (write(0xAB) != 0) delay(1); // ensure ID gets written, some hosts may be sensitive
while (write(0x83) != 0) delay(1); // this is critical for combined ports (they decide mouse/kb on this)
break;
case 0xF0: //set scan code set
ack();
if(!read(&val)) ack(); //do nothing with the rate
break;
case 0xEE: //echo
//ack();
delayMicroseconds(BYTE_INTERVAL_MICROS);
write(0xEE);
delayMicroseconds(BYTE_INTERVAL_MICROS);
break;
case 0xED: //set/reset LEDs
ack();
if(!read(leds)) ack(); //do nothing with the rate
//ack();
while (write(0xAF) != 0) delay(1);
if(!read(leds)) {
while (write(0xAF) != 0) delay(1);
}
#ifdef _PS2DBG
_PS2DBG.print("LEDs: ");
_PS2DBG.println(*leds, HEX);
Expand Down

0 comments on commit 961b013

Please sign in to comment.