Amiga 3000 keyboard to Arduino - jumbled data - always high

Hello,

I have Amiga 3000 and CDTV keyboards that are tested and known to be working. However, for the life of me I cannot seem to get the signals right with the Arduino in order to make the PS/2 interface possible (AMIGA 500/1000/2000 Keyboard Interface).

I've tried several permutations of the code (handshake timing 85-200 microseconds), wiring (swapping clock and data pins), yet nothing seems to work. The handshake seems to work but when reading the bits, they're all HIGH on the data line.

Could this be some noise stemming from the jumper cables? It seems unlikely that a keyboard would be this susceptible to noise. I've experimented with regular PS/2 keyboards and their clock and data signals work just fine, even with a super hacky connection job.

I've used the below code based on one snipped from elsewhere on these forums to test:

#define CLK 8
#define SP 9

void setup() {
  Serial.begin(9600);
  pinMode(CLK, INPUT);
  pinMode(SP, INPUT);
  digitalWrite(SP, LOW);
  pinMode(13, OUTPUT);
  delay(5000);
}

void loop() {
  int n;
  unsigned int d;
  bool y;
  long counter;
  
  // wait for beginning of synch-phase
  while (digitalRead(CLK)==HIGH);
  // wait for the clock going low
  while (digitalRead(CLK)==LOW);
  
 // Handshake must be given now
if (counter == 0)
 {
     pinMode(SP, OUTPUT);
     digitalWrite(SP, LOW);
     counter = micros();
 }
else if (micros() - counter > 200)
{
    counter = 0;
    pinMode(SP, INPUT);
    digitalWrite(SP, HIGH);
}

  // Now read 8 bit
  digitalWrite(13, HIGH);
  for (n=0; n<8; n++) {
    while (digitalRead(CLK)==LOW);
    d+=digitalRead(SP)<<n;
    while (digitalRead(CLK)==HIGH);
  }
  digitalWrite(13, LOW);
  Serial.println(d);
}

If anyone has gone through this with their Amiga 2000/3000/4000/CDTV keyboards I'd appreciate some insight as to what may be happening. I've retested the keyboards on real Amigas again and they work just fine.

I don't know if it will help but here is my translation of that sketch into Arduino code that doesn't use direct register access.

#include <Keyboard.h>
const byte ClockPin = 8;
const byte SPPin = 9;
const byte ResetPin = 10;

enum States {SYNCH_HI, SYNCH_LO, HANDSHAKE, READ, WAIT_LO, WAIT_RES} state;

uint32_t counter = 0;
uint8_t bitn, key, fn, keydown;

void setup()
{
  // Keyboard
  pinMode(ClockPin, INPUT);
  pinMode(SPPin, INPUT);
  pinMode(ResetPin, INPUT);
}


void loop()
{
  // Keyboard
  if ((digitalRead(ResetPin) == LOW) && state != WAIT_RES) // Reset
  {
    interrupts();
    //////////  Keyboard.write(0x4C);       // CTRL+ALT+DEL
    fn = 0;
    state = WAIT_RES;
  }
  else if (state == WAIT_RES)   // Waiting for reset end
  {
    if (digitalRead(ResetPin) == HIGH)
      state = SYNCH_HI;
  }
  else if (state == SYNCH_HI)   // Sync-Pulse HI
  {
    if (digitalRead(ClockPin) == LOW)
      state = SYNCH_LO;
  }
  else if (state == SYNCH_LO)   // Sync-Pulse LOW
  {
    if (digitalRead(ClockPin) == HIGH)
      state = HANDSHAKE;
  }
  else if (state == HANDSHAKE)  // Handshake
  {
    if (counter == 0)
    {
      pinMode(SPPin, OUTPUT);
      digitalWrite(SPPin, LOW);
      counter = millis();
    }
    else if (millis() - counter > 10)
    {
      counter = 0;
      pinMode(SPPin, INPUT);
      state = WAIT_LO;
      key = 0;
      bitn = 7;
    }
  }
  else if (state == READ)        // read key message (8 bits)
  {
    if (digitalRead(ClockPin) == HIGH)
    {
      if (bitn--)
      {
        key += (digitalRead(SPPin) == LOW) << (bitn); // key code (add bits 0...6)
                state = WAIT_LO;
      }
             else    // read last bit (key down)
      {
        keydown = digitalRead(SPPin) == HIGH; // true if key down
        interrupts();
        state = HANDSHAKE;
        
        /////////  PROCESS KEYPRESS HERE
      }
    }
  }
  else if (state == WAIT_LO)   // waiting for the next bit
  {
    if (digitalRead(ClockPin) == LOW)
    {
      noInterrupts();
      state = READ;
    }
  }
}

Thanks, John.

I don't think the issue was whether I used direct register access or not.

I managed to get it working now. I decided to take a "back to beginning" approach.

I analyzed the protocol using an oscope while referencing the hardware manuals and community code (some was correct, some was a bit off), then managed to nail down the handshake timing and bit layout algorithms.

This was quite fun as it was my first real usage of a scope and it was extremely educational and entertaining to match the reference manual with what I was seeing.

I'm looking forward to wrapping this up and using my Amiga keyboards with other systems.