Arduino Forum

Community => Exhibition / Gallery => Topic started by: olaf on Dec 27, 2012, 05:52 pm

Title: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Dec 27, 2012, 05:52 pm
Hi,

this turns your Arduino Leonardo into an AMIGA 500/1000/2000 Keyboard Interface which means that you can use your Amiga Keyboard as an HID Keyboard on your PC/Mac/PS3/Raspberry Pi or whatever. (like keyrah)
All you need is the Amiga Keyboard and the Arduino without any shield or additional hardware. It does not work with Amiga 600/1200 Keyboards since they have no serial interface.
It's also possible to hook up 2 digital joysticks (e.g. competition pro) with db9 connector.
see http://arduino.cc/forum/index.php?topic=134108.0

Based on Thomas Radtkes project http://www.raspberrypi.org/phpBB3/viewtopic.php?f=40&t=10990 I rewrote the code to make it faster and smaller. I also changed the behavier a little bit to match my own preferences.

The Keyboard must be connected to digital inputs 8,9,10 , GND and 5V. The Power LED can be directly connected to 5V
This is the pin assignment:

Code: [Select]
Keyboard   Leonardo
Connector  IO           

1   KBCLK   8
2   KBDATA  9
3   KBRST   10
4   5v      5v
5   NC
6   GND     GND
7   LED1    5V
8   LED2    -


This is the sketch for German QWERTZ Layout:
See Page 2 for QWERTY Layout (thanks Steve_Reaver)

Code: [Select]
#define BITMASK_A500CLK 0b00010000    // IO 8
#define BITMASK_A500SP  0b00100000    // IO 9
#define BITMASK_A500RES 0b01000000    // IO 10
#define BITMASK_JOY1    0b10011111    // IO 0..4,6
#define BITMASK_JOY2    0b11110011    // IO A0..A5    
#define SYNCH_HI        0
#define SYNCH_LO        1
#define HANDSHAKE       2
#define READ            3
#define WAIT_LO         4
#define WAIT_RES        5

KeyReport _keyReport;
uint32_t counter = 0;
uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn,keydown, ktab[0x68]={
 // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
 0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
 // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
 0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
 // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
 0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
 // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
 0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
 // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
 0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
 // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
 // modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Win (amiga) left, Ctrl (amiga)right
 0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0x08, 0x10
};

void setup() {
 // Joystick 1 (Port D)
 DDRD = ~BITMASK_JOY1; // direction INPUT
 PORTD = BITMASK_JOY1; // activate PULLUP
 
 // Joystick 2 (Port F)
 DDRF = ~BITMASK_JOY2; // direction INPUT
 PORTF = BITMASK_JOY2; // activate PULLUP

 // Keyboard (Port B)
 DDRB = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT
}


void loop() {
 // Joystick 1
 Joy = ~PIND & BITMASK_JOY1;
 if (Joy != MemoJoy1) {
   HID_SendReport(3, &Joy, 1);
   MemoJoy1 = Joy;
 }  

// Joystick 2
 Joy = ~PINF & BITMASK_JOY2;
 if (Joy != MemoJoy2) {
   HID_SendReport(4, &Joy, 1);
   MemoJoy2 = Joy;
 }  
 
 // Keyboard
   if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {   // Reset
   interrupts();
   keystroke(0x4C,05);        // CTRL+ALT+DEL
   fn=0;
   state=WAIT_RES;
 }
 
 else if (state==WAIT_RES) {   // Waiting for reset end
   if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
 }
 
 else if (state==SYNCH_HI) {   // Sync-Pulse HI
   if ((PINB & BITMASK_A500CLK)==0) state=SYNCH_LO;
 }

 else if (state==SYNCH_LO) {   // Sync-Pulse LOW
   if ((PINB & BITMASK_A500CLK)!=0) state=HANDSHAKE;
 }

 else if (state==HANDSHAKE) {  // Handshake
   if (counter==0) {
     DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
     PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
     counter=millis();
   }
   else if (millis()-counter>10) {
     counter=0;
     DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
     state=WAIT_LO;
     key=0;
     bitn=7;
   }
 }
 
 else if (state==READ) {        // read key message (8 bits)
   if ((PINB & BITMASK_A500CLK)!=0) {  
     if (bitn--){
       key+=((PINB & BITMASK_A500SP)==0)<<(bitn); // key code (add bits 0...6)
       state=WAIT_LO;
     }
     else {  // read last bit (key down)    
       keydown=((PINB & BITMASK_A500SP)!=0); // true if key down
       interrupts();
       state=HANDSHAKE;
       if (key==0x5F)  fn=keydown;  // "Help" key: special function on/off
       else if (key==0x62) keystroke(0x39,0x00);  // CapsLock
       else {
         if (keydown){
           // keydown message received
           if (fn) {
             // special function with "Help" key
             if (key==0x50) keystroke(0x44,0);  // F11
             else if (key==0x51) keystroke(0x45,0);  // F12
             else if (key==0x5A) keystroke(0x53,0);  // NumLock
             else if (key==0x5B) keystroke(0x47,0);  // ScrollLock
             else if (key==0x5D) keystroke(0x46,0);  // PrtSc
             else if (key==0x02) keystroke(0x14,0x40);  // @
             else if (key==0x04) keystroke(0x35,0x02);  // °
           }
           else {
             if ((key==0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35,0x00);  // ^ (with shift)
             else if (key==0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30,0x40); else keystroke(0x35,0x20); // ~,`
             else if (key==0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64,0x40); else keystroke(0x2D,0x40); // |,BS
             else if (key==0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24,0x40); else keystroke(0x25,0x40); // {,[
             else if (key==0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27,0x40); else keystroke(0x26,0x40); // },]
             else if (key < 0x68) keypress(key);  // Code table
           }
         }
         else {
           // keyrelease message received
           if (key < 0x68) keyrelease(key);  // Code table
         }
       }
     }
   }
 }
 
 else if (state==WAIT_LO) {   // waiting for the next bit
   if ((PINB & BITMASK_A500CLK)==0) {
     noInterrupts();
     state=READ;
   }
 }
}
   

void keypress(uint8_t k) {
 
 if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
 else {  
   for (uint8_t i=0; i<6; i++) {
     if (_keyReport.keys[i] == 0) {
        _keyReport.keys[i] = ktab[key];
        break;
     }
   }
 }
 HID_SendReport(2,&_keyReport,8);
}


void keyrelease(uint8_t k) {

 if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
 else {  
   for (uint8_t i=0; i<6; i++) {
     if (_keyReport.keys[i] == ktab[key]) _keyReport.keys[i] = 0;
   }
 }
 HID_SendReport(2,&_keyReport,8);
}


void keystroke(uint8_t k, uint8_t m) {
 
 unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
   for (uint8_t i=0; i<6; i++) {
     if (_keyReport.keys[i] == 0) {
        _keyReport.keys[i] = k;
        _keyReport.modifiers = m;
        HID_SendReport(2,&_keyReport,8);
        _keyReport.keys[i] = 0;
        _keyReport.modifiers = memomodifiers; // recover modifier state
        HID_SendReport(2,&_keyReport,8);
        break;
     }
   }
}


Since I never owned a real Amiga I prefer the IBM layout for the modifier keys CTRL,ALT, etc.
So If you want to have IBM layout swap the key caps on the keyboard and exchange the following codeline:

Code: [Select]
   // modifiers: Shift left, Shift right, -, Win left, Crtl left, Ctrl right, Alt left, Alt right
     0x02, 0x20, 0x00, 0x08, 0x01, 0x10, 0x04, 0x40


best regards
Olaf
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: keeper63 on Feb 06, 2013, 04:15 am
This would definitely make Amiga emulation (Amiga Forever and the like) systems more interesting - Glad I kept my 2000 and keyboard around...
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Farb on Feb 06, 2013, 05:16 pm
Hi!

I've uploaded the script with joystick function but nothing happens when I press the buttons or move around with the joystick. The arduino seems to register every button and movement on the tx led.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Feb 07, 2013, 01:04 am
Hi ,
did you put the HID gamepad descriptor in HID.c  as described in http://arduino.cc/forum/index.php?PHPSESSID=c2389e555cb5a98aa144984413bcf5d0&topic=134108.0 ?
Can you see the  2  joysticks in start/ system /  gamecontroller  ?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: MikePig on Feb 07, 2013, 12:09 pm
Hi,

Great work my A4000 keyboard is working on my Pegasos II !

However I have a couple of questions :

-Would it be a possible to get a PS/2 outpout on spare arduino's pins and how difficult would it be to modify the sketch to get this to work ?
-As the A4000 keyboard doesn't have the kbrst signal is it possible to make the arduino act as a reset switch hooked to the motherboard after reading the CTRL-A-A keypress sequence ?
-The CTRL-A-A seems to freeze the arduino so that I have to push the reset switch on the leonardo board to get it work again ...

As I said it befor it is an A4000 keyboard and this differs from A500 and A2000 keyboards since it hasn't the electrical reset line only clock and data line

Regards

Michel
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Farb on Feb 08, 2013, 11:58 am
I had some issues with putting the code in the HID.cpp 

"1.0.3\hardware\arduino\cores\arduino\HID.cpp:420: error: expected unqualified-id before numeric constant"

But the other funny thing is that the Tac-2's wiring is

Front
Back
Left
Right
GND
Button

So I can't find any 5v wire, so I wired up the cables with your diagram and as I mentioned before it registers on TX led that something is moving of being pressed on the joystick.

Would it be possible if you uploaded a HID.cpp file that is configured or the code of the HID.cpp.
And thanks for all your hard work:)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Feb 09, 2013, 12:09 pm
@MikePig:
-Would it be a possible to get a PS/2 outpout on spare arduino's pins and how difficult would it be to modify the sketch to get this to work ?
I guess this might be possible.
please visit kbdbabel.org . there you'll find an amiga to ps2 converter with the related sourcecode. maybe you can use this as a template.

-As the A4000 keyboard doesn't have the kbrst signal is it possible to make the arduino act as a reset switch hooked to the motherboard after reading the CTRL-A-A keypress sequence ?
This could work if the amiga keyboard controller transmits the CTRL-A-A sequence on the dataline.
The motherboard RESET input normally needs a GND signal. So one have to try if the arduino output switched to LOW will be enough. Otherwise you'll need an additional transistor, like a FET, that switches to GND.

-The CTRL-A-A seems to freeze the arduino so that I have to push the reset switch on the leonardo board to get it work again ...
I haven't noticed this with the A500 keyboard. maybe it helps to add a case for CTRL-A-A in the sketch
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Feb 09, 2013, 01:12 pm
@Farb:
+5V is only needed if the joystick contains circuits like autofire,...

attached is my hid.cpp...
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Feb 09, 2013, 01:16 pm
@all:  
the code is  made for a german keyboard layout, for other layouts the keytable and parts of the code have to be modified.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Farb on Feb 09, 2013, 08:20 pm
Thank you! It all works now. But I had to configure some stuff:)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Feb 12, 2013, 11:31 pm
update: 
"{","[" had no function - fixed
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Splashdust on Mar 06, 2013, 04:42 pm
Hi!

I'm building a PC-in-a-A1200-case, and are attempting to get this code to work with a A500 kbd (which fits perfectly in a A1200 case btw). Initially I bought a Keyrah to use as a KBD adapter, but it turned out to be a C64/128 specific one so I figured I might be able to do it with an Arduino instead. Fortunately I found this sketch so I won't have to do it all from scratch :)

However, I keep getting a repeated key press of the ">"-key when I plug in the keyboard. I get no other response. The power led is lit up and the caps lock key works for 10 seconds or so (i.e the little led lights up in the key), but then it stops responding. Maybe there is some issue with the initial handshake?

I'm fairly new to Arduino and hardware hacking in general, so right now I'm at the stage where I'm not really sure where to start troubleshooting. Any pointers would be very helpful!

BTW, I'm using the Arduino Micro, but AFAIK it's the same chip as the Leonardo, but on a smaller PCB, so the same sketch should work right?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Splashdust on Mar 06, 2013, 05:06 pm
Never mind. Got it working! Typing this on my A500 KBD :)

Turns out the the pin mapping was wrong. Data should be 8 and clock should be 9. Olaf, you might want to change this in your original post!

Anyways, thanks for the sketch!
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Mar 11, 2013, 12:20 pm
@Splashdust, You're right. Data and Clock were swapped. I changed it in the original post. Thank you.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Jenot on Sep 12, 2013, 08:11 am
Everything is OK with PC/Windows and OSX but i have mist (Atari and Amiga FPGA clone). It seems like Arduino is not recognized as HID keyboard. I see blinking TX LED so keycodes are send to mist but no reaction in mist menu nor amiga software.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: fjutrackx on Oct 22, 2013, 12:33 pm
Well, the next part of the project would be: A computer keyboard to amiga A500 / 1000 / 2000 / 4000 xd. Some people like me prefers to use a real Amiga, but a working keyboard is my problem right now. So why not build a ps2 PC to ps2 amiga convertor. Ok, you can buy it for only 30 euro but that's the too easy way and i want it "now" xd.
And once the code is written and tested everyone could built one, cheaper then the ones you can buy.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Steve_Reaver on Nov 24, 2013, 10:23 pm
Thanks everyone I have been able successfully  to build this and is  big step towards finishing  my awesome Amiga emulator project!  But I found that the code did not work perfectly with US Qwerty keyboard map, so I have fixed that, and I have also added code for PrtScrn, which was not there.

Code: [Select]
#define BITMASK_A500CLK 0b00010000    // IO 8
#define BITMASK_A500SP  0b00100000    // IO 9
#define BITMASK_A500RES 0b01000000    // IO 10
#define BITMASK_JOY1    0b10011111    // IO 0..4,6
#define BITMASK_JOY2    0b11110011    // IO A0..A5   
#define SYNCH_HI        0
#define SYNCH_LO        1
#define HANDSHAKE       2
#define READ            3
#define WAIT_LO         4
#define WAIT_RES        5

KeyReport _keyReport;
uint32_t counter = 0;
uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn,keydown, ktab[0x68]={
  // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
  0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
  // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
  0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
  // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
  0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
  // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
  0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
  // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
  0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
  // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
  0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
  // modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Win (amiga) left, Ctrl (amiga)right
  0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0x08, 0x10
};

void setup() {
  // Joystick 1 (Port D)
  DDRD = ~BITMASK_JOY1; // direction INPUT
  PORTD = BITMASK_JOY1; // activate PULLUP
 
  // Joystick 2 (Port F)
  DDRF = ~BITMASK_JOY2; // direction INPUT
  PORTF = BITMASK_JOY2; // activate PULLUP

  // Keyboard (Port B)
  DDRB = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT
}


void loop() {
  // Joystick 1
  Joy = ~PIND & BITMASK_JOY1;
  if (Joy != MemoJoy1) {
    HID_SendReport(3, &Joy, 1);
    MemoJoy1 = Joy;
  } 

// Joystick 2
  Joy = ~PINF & BITMASK_JOY2;
  if (Joy != MemoJoy2) {
    HID_SendReport(4, &Joy, 1);
    MemoJoy2 = Joy;
  } 
 
  // Keyboard
    if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {   // Reset
    interrupts();
    keystroke(0x4C,05);        // CTRL+ALT+DEL
    fn=0;
    state=WAIT_RES;
  }
 
  else if (state==WAIT_RES) {   // Waiting for reset end
    if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
  }
 
  else if (state==SYNCH_HI) {   // Sync-Pulse HI
    if ((PINB & BITMASK_A500CLK)==0) state=SYNCH_LO;
  }

  else if (state==SYNCH_LO) {   // Sync-Pulse LOW
    if ((PINB & BITMASK_A500CLK)!=0) state=HANDSHAKE;
  }

  else if (state==HANDSHAKE) {  // Handshake
    if (counter==0) {
      DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
      PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
      counter=millis();
    }
    else if (millis()-counter>10) {
      counter=0;
      DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
      state=WAIT_LO;
      key=0;
      bitn=7;
    }
  }
 
  else if (state==READ) {        // read key message (8 bits)
    if ((PINB & BITMASK_A500CLK)!=0) { 
      if (bitn--){
        key+=((PINB & BITMASK_A500SP)==0)<<(bitn); // key code (add bits 0...6)
       
        state=WAIT_LO;
      }
      else {  // read last bit (key down)   
        keydown=((PINB & BITMASK_A500SP)!=0); // true if key down
        interrupts();
        state=HANDSHAKE;
        if (key==0x5F)  fn=keydown;  // "Help" key: special function on/off
        else if (key==0x62) keystroke(0x39,0x00);  // CapsLock
        else {
          if (keydown){
            // keydown message received------
            if (fn) {
              // special function with "Help" key
              if (key==0x50) keystroke(0x44,0);  // F11
              else if (key==0x51) keystroke(0x45,0);  // F12
              else if (key==0x5A) keystroke(0x53,0);  // NumLock
              else if (key==0x5B) keystroke(0x47,0);  // ScrollLock
              else if (key==0x5D) keystroke(0x46,0);  // PrtSc
            }
            else {
              if (key==0x5A) keystroke(0x26,0x20); // (
              else if (key==0x5B) keystroke(0x27,0x20); // )
              else if (key < 0x68) keypress(key);  // Code table
            }
          }
          else {
            // keyrelease message received
            if (key < 0x68) keyrelease(key);  // Code table
          }
        }
      }
    }
  }
 
  else if (state==WAIT_LO) {   // waiting for the next bit
    if ((PINB & BITMASK_A500CLK)==0) {
      noInterrupts();
      state=READ;
    }
  }
}
   

void keypress(uint8_t k) {
 
  if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
  else { 
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = ktab[key];
         break;
      }
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keyrelease(uint8_t k) {

  if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
  else { 
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == ktab[key]) _keyReport.keys[i] = 0;
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keystroke(uint8_t k, uint8_t m) {
 
  unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = k;
         _keyReport.modifiers = m;
         HID_SendReport(2,&_keyReport,8);
         _keyReport.keys[i] = 0;
         _keyReport.modifiers = memomodifiers; // recover modifier state
         HID_SendReport(2,&_keyReport,8);
         break;
      }
    }
}


If you are hacking this code or testing your keyboard you may find these resources useful;
  Keyboard Tester - http://www.keyboardtester.com/
  Keyboard Scancode reader - http://delphiforfun.org/programs/utilities/KeyCodes.htm
  Keyboard scancodes explained - http://www.quadibloc.com/comp/scan.htm
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Dec 04, 2013, 12:30 pm
Thank you Steve,
I added PrtSc in my  original Sketch and made a hint to your QWERTY Layout in the first  post.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: fl0w3n on Jan 22, 2014, 06:30 am
Sorry to revive a thread from the dead, but I just picked up an Amiga 2000 and my first ever Arduino.  I am a keyboard enthusiast which is what led me to the Amiga 2000, with the intention that I'd be able to use it based off the information I found in this thread and a Leonardo that I purchased.

Basically, I'm a script kiddie. 

I'm running into an issue, when I "Verify" the Copy Pasta I did from Steve_Reaver I get back an error that 'KeyReport' does not name a type.  Here's the log:

Code: [Select]

Amiga_2000_QWERTY_Copy_Pasta:13: error: 'KeyReport' does not name a type
Amiga_2000_QWERTY_Copy_Pasta.ino: In function 'void setup()':
Amiga_2000_QWERTY_Copy_Pasta:38: error: 'DDRF' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:39: error: 'PORTF' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta.ino: In function 'void loop()':
Amiga_2000_QWERTY_Copy_Pasta:50: error: 'HID_SendReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:55: error: 'PINF' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:57: error: 'HID_SendReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta.ino: In function 'void keypress(uint8_t)':
Amiga_2000_QWERTY_Copy_Pasta:146: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:149: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:155: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:155: error: 'HID_SendReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta.ino: In function 'void keyrelease(uint8_t)':
Amiga_2000_QWERTY_Copy_Pasta:161: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:164: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:167: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:167: error: 'HID_SendReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta.ino: In function 'void keystroke(uint8_t, uint8_t)':
Amiga_2000_QWERTY_Copy_Pasta:173: error: '_keyReport' was not declared in this scope
Amiga_2000_QWERTY_Copy_Pasta:178: error: 'HID_SendReport' was not declared in this scope


I gotta assume Steve's code is good and since all I did was copy and paste, I gotta assume it's something wrong on my side.

Any input?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: fl0w3n on Feb 03, 2014, 06:04 am
So it looks like I need to include a library of some sort, and I've tried all the libraries that the Arduino 1.0.5 IDE comes with but none of them worked. 

Can anyone help?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: fl0w3n on Mar 02, 2014, 07:49 am
Well, as I suspected, the issue was very simple and a case of being a newb.

The IDE was not set to Leonardo, and I needed to "select drivers from list" for the Leonardo and Leonardo Bootloader, and disable my Bluetooth in Device Manager.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: PhysicalPixel on Jun 05, 2014, 07:29 pm
Thanks for this code!

I just bought an Arduino Micro and connected an Amiga 2000 keyboard (the Cherry one!) to my MacBook and it's working!

As this keyboard doesn't have separate reset line, I had to remove the parts of the code (about waiting for the reset line) to get it working. Just wanted to point this out in case somebody else tries this with another 5-pin Amiga keyboard.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: esvee on Oct 06, 2014, 09:18 pm
Bump! I'm trying to use this code on an Amiga 2000 keyboard just like PhysicalPixel but I'm not having much luck removing the rest code. Any enlightenment would be awesome.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Sjamaan on Nov 25, 2014, 07:08 am
I have been using this for a few months now...and recently I am getting stuck repeating keys...anyone else have this problem...I have checked ground and connections...next thing to do is try another arduino leonardo....?

anyway...wonder if any of the code changes that you made to the original have timing issues or if this is just a purely hardware problem with my setup...

Cheers!
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: koney on Jan 11, 2015, 12:59 pm
Hey all!

as a newbie I managed to assemble the project successfully with a spare Amiga 500. I even wrote down some extra HELP key functions that were missing or not enough accessible.

HELP + Arrows will navigate page up/down and end/home
HELP + DEL activates INS
HELP + Return fires another PrintSCR, easier with just one hand.

Code: [Select]

                // MORE HELP FUNCTIONS  ///////////////////////////////
                else if (key==0x4c) keystroke(0x4b,0);  // Up = PgUp
                else if (key==0x4d) keystroke(0x4e,0);  // Down = PgDown
                else if (key==0x4f) keystroke(0x4a,0);  // Left = Home
                else if (key==0x4e) keystroke(0x4d,0);  // Right = End
                else if (key==0x46) keystroke(0x49,0);  // Help + DEL = Ins
                else if (key==0x44) keystroke(0x46,0);  // Help + RETURN = PrtSc 2   
                ////////////////////////////////////////////////////////



THANK YOU! :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: PereatMundus on Jan 12, 2015, 05:54 pm
Hi,
and thanks for the code!

Having issues thou.

I'm forth in this thread trying to get the code working on a 5pin amiga keyboard however. (CDTV, A4000 etc). Probably should be more trying this since the most liked keyboard is infact the black CDTV mitsumi tactile keyboard.

From what I can tell It should work just by removing the reset code, However I've tried removing all / parts and various variants of removal of the code cited to do with reset KBRST and waiting for reset, without any luck.

PhysicalPixel got this to work. please someone what should be removed . Exactly?

Since esveee didnt seem to get it to work as well as myself and I'm sure there are others not posting. please someone detail the edits in the code for us That fail with this.
help!
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: koney on Jan 13, 2015, 09:46 pm
Here again to ask for some help!

I'm trying to map a few more keys, this time would be multimedia vol up/down and mute:

Code: [Select]
               
// VOLUME KEYS //
else if (key==0x5e) keystroke(0x80,0);  // Help + + = VOL UP
else if (key==0x4a) keystroke(0x81,0);  // Help + - = VOL DOWN
else if (key==0x43) keystroke(0x7f,0);  // Help + enter = VOL MUTE


keystroke values should be correct because I cross checked them from multiple sources. They should correspond to 128 and 129 but using a keyboard monitor I can't see ANY activitiy coming from them. Now my suspect is that the HID interface supports only values <101. Is it possible? how can I solve this problem, eventually?

again, thanks in advance :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: koney on Jan 13, 2015, 11:18 pm
OK, I managed to do it by myself by udating HID code from here http://stefanjones.ca/blog/arduino-leonardo-remote-multimedia-keys/ (http://stefanjones.ca/blog/arduino-leonardo-remote-multimedia-keys/)
(it says to just change two files but it didn't work for me until I replaced the whole hardware\arduino\cores\arduino folder with the one from the repository)

and adding this to the list of HELP keys:

Code: [Select]

// VOLUME KEYS //
else if (key==0x5e) { Remote.increase(); Remote.clear();}  // Help + + = VOL UP
else if (key==0x4a) { Remote.decrease(); Remote.clear();}  // Help + - = VOL DOWN
else if (key==0x43) { Remote.mute(); Remote.clear();}      // Help + enter = VOL MUTE


Tested on a WIN7 machine, works nicely ;)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DioxCorp on Apr 30, 2015, 01:07 pm
I'm trying to do the same setup: convert a defunct amiga 500 into a usb keyboard + 2 joysticks with a spare Arduino.

The issues is that the arduino that I've for testing is a Nano with a ATmega328 chip, not a ATmega32u4 like the micro or the leonardo. It does not seem to include the keyboard support library: it reports errors as _keyReport as an undefined type, like with fl0w3n.

Is it truly unsupported, or do I need to add it manually somehow? I would preffer a solution that would help me use the hardware I have.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Jens1976 on Dec 27, 2015, 02:07 pm
Hello, does anyone knows how to activate the Arrow-Keys an the Num-Block?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olivier78860 on Jan 05, 2016, 03:51 pm
Hi all,

This is 2016 and some things had to be done to adapt the source code Olaf wrote to the 1.6.9 IDE with the Arduino Leonardo Rev 4.0.
Forgive me if it sounds absolutely obvious to everyone else, but I prefer to link to the question I asked, in case it is helpful to anyone, as noob as I am !

http://forum.arduino.cc/index.php?topic=369773.0

Code: [Select]

#include <Keyboard.h> // FOR NEWEST IDE 1.6.9

#define BITMASK_A500CLK 0b00010000    // IO 8
#define BITMASK_A500SP  0b00100000    // IO 9
#define BITMASK_A500RES 0b01000000    // IO 10
#define SYNCH_HI        0
#define SYNCH_LO        1
#define HANDSHAKE       2
#define READ            3
#define WAIT_LO         4
#define WAIT_RES        5
#define HID_SendReport(id,data,len) HID().SendReport(id,data,len) // IDE 1.6.9
KeyReport _keyReport;
uint32_t counter = 0;
uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn,keydown, ktab[0x68]={
  // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
  0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
  // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
  0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
  // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
  0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
  // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
  0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
  // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
  0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
  // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
  0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
  // modifiers: Shift left, Shift right, -, Win left, Crtl left, Ctrl right, Alt left, Alt right
  0x02, 0x20, 0x00, 0x08, 0x01, 0x10, 0x04, 0x40
};

void setup() {
 // Keyboard (Port B)
  DDRD = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT
}

void loop() {
 
  // Keyboard
    if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {   // Reset
    interrupts();
    keystroke(0x4C,05);        // CTRL+ALT+DEL
    fn=0;
    state=WAIT_RES;
  }
 
  else if (state==WAIT_RES) {   // Waiting for reset end
    if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
  }
 
  else if (state==SYNCH_HI) {   // Sync-Pulse HI
    if ((PINB & BITMASK_A500CLK)==0) state=SYNCH_LO;
  }

  else if (state==SYNCH_LO) {   // Sync-Pulse LOW
    if ((PINB & BITMASK_A500CLK)!=0) state=HANDSHAKE;
  }
 
  else if (state==HANDSHAKE) {  // Handshake
    if (counter==0) {
      DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
      PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
      counter=millis();
    }
    else if (millis()-counter>10) {
      counter=0;
      DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
      state=WAIT_LO;
      key=0;
      bitn=7;
    }
  }
 
  else if (state==READ) {        // read key message (8 bits)
    if ((PINB & BITMASK_A500CLK)!=0) {
      if (bitn--){
        key+=((PINB & BITMASK_A500SP)==0)<<(bitn); // key code (add bits 0...6)
        state=WAIT_LO;
      }
      else {  // read last bit (key down)   
        keydown=((PINB & BITMASK_A500SP)!=0); // true if key down
        interrupts();
        state=HANDSHAKE;
        if (key==0x5F)  fn=keydown;  // "Help" key: special function on/off
        else if (key==0x62) keystroke(0x39,0x00);  // CapsLock
        else {
          if (keydown){
            // keydown message received
            if (fn) {
              // special function with "Help" key
              if (key==0x50) keystroke(0x44,0);  // F11
              else if (key==0x51) keystroke(0x45,0);  // F12
              else if (key==0x5A) keystroke(0x53,0);  // NumLock
              else if (key==0x5B) keystroke(0x47,0);  // ScrollLock
              else if (key==0x02) keystroke(0x14,0x40);  // @
              else if (key==0x04) keystroke(0x35,0x02);  // °
            }
            else {
              if ((key==0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35,0x00);  // ^ (with shift)
              else if (key==0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30,0x40); else keystroke(0x35,0x20); // ~,`
              else if (key==0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64,0x40); else keystroke(0x2D,0x40); // |,\
              else if (key==0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24,0x40); else keystroke(0x25,0x40); // {,[
              else if (key==0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27,0x40); else keystroke(0x26,0x40); // },]
              else if (key < 0x68) keypress(key);  // Code table
            }
          }
          else {
            // keyrelease message received
            if (key < 0x68) keyrelease(key);  // Code table
          }
        }
      }
    }
  }
 
  else if (state==WAIT_LO) {   // waiting for the next bit
    if ((PINB & BITMASK_A500CLK)==0) {
      noInterrupts();
      state=READ;
    }
  }
}


void keypress(uint8_t k) {
 
  if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
  else {
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = ktab[key];
         break;
      }
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keyrelease(uint8_t k) {

  if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
  else {
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == ktab[key]) _keyReport.keys[i] = 0;
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keystroke(uint8_t k, uint8_t m) {
 
  unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = k;
         _keyReport.modifiers = m;
         HID_SendReport(2,&_keyReport,8);
         _keyReport.keys[i] = 0;
         _keyReport.modifiers = memomodifiers; // recover modifier state
         HID_SendReport(2,&_keyReport,8);
         break;
      }
    }
}



On a side note, I had to swap pins 8 & 9 for it to work. It seems it is Amiga-keyboard dependent. If it doesn't work with the proposed setup, just swap the cables connected to these pins.

And my deepest thanks to the nice people who wrote that code and to the person who gave me the issue's solution :)

Of course, this is typed with my A500 keyboard :D
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: chking on Jan 05, 2016, 04:10 pm
I'm working on this same project and found I also had to swap pins 8 and 9.  Once I do that though the keyboard outputs a stream of ~ characters.  I took apart the keyboard to clean it and I'm concerned that I might have ruined it or not put it back together correctly.  Anyone else run into problems like this?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olivier78860 on Jan 05, 2016, 06:51 pm
I had exactly the same issue.

I uploaded the empty program to the Arduino, then unplugged it, and then reuploaded the program to the Arduino.

Also, check your connections and change the USB cable. I had two, one generic and one from my Samsung smartphone. Only the Samsung one gave good results.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olaf on Jan 06, 2016, 02:54 pm
Dear Olivier,

Please apologize my delayed answer. I read your mail today and saw that you have fixed the problem allready.
Many thanks for publishing the solution in this thread!

Yes , it`s a long time ago I made this code, but it still works surprisingly well ;-).
I use the keyboard on my retro amiga notebook conversion every day. I`m actually writing this post on the Amiga Keyboard. Attached are some pictures of my Amiga 500 conversion.

I hope your amiga project  works as well and my code is usefull for you and all other members.

yours sincerely
Olaf
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: chking on Jan 06, 2016, 04:31 pm
Olaf, in your pictures, what are the two big green components connected to 5 volts and ground?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olivier78860 on Jan 07, 2016, 11:23 am
Those are condensators. I suspect it's to make sure the disk and power led get the constant 5V they need, as I have read somewhere that the Arduino couldn't provide with constant current.

If the specs of these condensators could be given, that would be nice !

And thanks Olaf for the code again :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: RetroMachine on Jan 23, 2016, 07:42 am
I have this working and have wired up an A500 keyboard :)

Thanks Olaf and olivier78860
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: kolla on Jan 24, 2016, 07:50 pm
Hello, I have a slightly similar potential project I am pondering on :) Instead of USB hid, I want old school PS/2, so I can use real Amiga keyboard and mouse on my Minimig. That is a nice little project in itself, but it would be even more awesome if I manage to have one arduino connected to the PS/2 ports on the Minimig and another arduino to the Amiga keyboard and mouse, the two arduinos communicating wirelessly. And then think further, what if there are multiple systems (my Minimig (PS/2), my MIST (USB hid)and my CD32 (Amiga mini-DIN)) and I want to control them all from one remote unit, which acts like a wireless keyboard+mouse+joysticks switch... one can dream :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: builder_guy on Jan 24, 2016, 11:17 pm
Very cool.  Long live amiga!
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olivier78860 on Feb 18, 2016, 09:14 am
And my project, finally completed yesterday.
http://imgur.com/gallery/GvEMv
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Feb 18, 2016, 08:36 pm
Olaf, in your pictures, what are the two big green components connected to 5 volts and ground?
They do NOT look like capacitors, they look like large multi-watt resistors. But the images are too small to tell.

Olaf?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DJulius on Apr 25, 2016, 02:08 pm
Hi, i got amiga 500 with a azerty keyboard, i would like to modify the code but i don't know how to do that, can you help me ?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: olivier78860 on Apr 27, 2016, 10:04 pm
Djulius,
You can use the code as it is.
When installing Linux, just set your keyboard to French and the keys will be correctly assigned (there are imperfections due to the differences between back-in-the-day Amiga azerty and nowaday's PC azerty, though, especially on the number keys above the letters' alternates).
That's what I did and it works just fine.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Silver Dream on May 25, 2016, 09:23 pm
Hi all,

This is 2016 and some things had to be done to adapt the source code Olaf wrote to the 1.6.9 IDE with the Arduino Leonardo Rev 4.0.
Forgive me if it sounds absolutely obvious to everyone else, but I prefer to link to the question I asked, in case it is helpful to anyone, as noob as I am !
Thank you for posting this. It saved me some time for sure. Summing up the changes - in order to compile the sketch cleanly within the Arduino 1.6.9, the following changes need to be made:

Code: [Select]

#include <Keyboard.h> // FOR NEWEST IDE 1.6.9

[...]

  DDRD = ~(BITMASK_JOY1); // direction INPUT
  DDRF = ~(BITMASK_JOY2); // direction INPUT
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: szczuru on May 27, 2016, 10:24 pm
Can it be combined with dual Amiga Joysticks (on Arduino Nano)? From here:
http://forum.arduino.cc/index.php?topic=134108.0
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: devrim on Aug 11, 2016, 09:54 pm
Do I need to add any lines to HID.cpp for Joysticks?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: gamradek on Aug 26, 2016, 10:53 am
Hi guys,
I want to convert my Amiga 500 to HID keyboard. As it is 2016 and Anduino boards are probably updated, I want to know which version of the code I should upload. The original one was edited in 2013. I saw a different one further in this thread. I probably buy this set ( https://botland.com.pl/zestawy-startowe-dla-arduino/1846-starterkit-elektro-przewodnik-z-modulem-arduino-leonardo.html#/wyswietlacz_lcd-niebieski ). I saw a few modifications being made in the thread regarding the code. I want to use classic IBM layout. I would appreciate someone help me find the proper code, because I got confused which one should I use, or what should be done prior to programming the board. I'm a newbie in the field of programming modules like that or creating custom hardware. :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: rickmk on Dec 08, 2016, 10:17 pm
Do I need to add any lines to HID.cpp for Joysticks?
Any luck with this ??

So many IDE changes and so many different versions of code, I'm lost as to what is the right code for working joysticks with IDE V 1.6.13.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: saint613 on Dec 16, 2016, 03:49 pm
If any one is still paying attention to this thread I'm trying to stumble through a problem, I can't figure out why my shift key's don't function. Caps lock works. Any thoughts?

Thanks in advance!
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: dally on Dec 24, 2016, 01:47 pm
Interesting project
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: CypherXG on Jan 12, 2017, 02:56 pm
Hello.

Can someone fix this:

The Reset Keys

Normal with Winuae or Uae4arm the reset keys are
Left CTRL, Left Win, right Menu

In the Code are the Keys
Left Win, Left ALT, Right ALT.
So a normal reset on Emulators does not work.
What are the correct Hex Keys, because i did not found Right Menu.

Pls Help


Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: JensBe on Jan 26, 2017, 06:16 pm
Hi there,
I´m a newbee in arduino.
I used the code from Olaf, and it works.

But.....

I have some Problems with some keys: Especially S,W, the 2 in the upper number line of the anmiga keyboard, the ", too. They are delayed. The delay is about 1 - 3 seconds. Does anyone know what to do, that this no longer happens?

Here´s the code for my Arduino Leonardo:

#include <Keyboard.h>





#define BITMASK_A500CLK 0b00010000    // IO 8
#define BITMASK_A500SP  0b00100000    // IO 9
#define BITMASK_A500RES 0b01000000    // IO 10
#define SYNCH_HI        0
#define SYNCH_LO        1
#define HANDSHAKE       2
#define READ            3
#define WAIT_LO         4
#define WAIT_RES        5
#define HID_SendReport(id,data,len) HID().SendReport(id,data,len) // IDE 1.6.9
KeyReport _keyReport;
uint32_t counter = 0;
uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn, keydown, ktab[0x68] = {
  // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
  0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
  // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
  0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
  // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
  0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
  // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
  0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
  // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
  0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
  // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
  0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
  // modifiers: Shift left, Shift right, -, Win left, Crtl left, Ctrl right, Alt left, Alt right
  0x02, 0x20, 0x00, 0x08, 0x01, 0x10, 0x04, 0x40
};

void setup() {
  // Keyboard (Port B)
  DDRD = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT
}

void loop() {

  // Keyboard
  if (((PINB & BITMASK_A500RES) == 0) && state != WAIT_RES) { // Reset
    interrupts();
    keystroke(0x4C, 05);       // CTRL+ALT+DEL
    fn = 0;
    state = WAIT_RES;
  }

  else if (state == WAIT_RES) { // Waiting for reset end
    if ((PINB & BITMASK_A500RES) != 0) state = SYNCH_HI;
  }

  else if (state == SYNCH_HI) { // Sync-Pulse HI
    if ((PINB & BITMASK_A500CLK) == 0) state = SYNCH_LO;
  }

  else if (state == SYNCH_LO) { // Sync-Pulse LOW
    if ((PINB & BITMASK_A500CLK) != 0) state = HANDSHAKE;
  }

  else if (state == HANDSHAKE) { // Handshake
    if (counter == 0) {
      DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
      PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
      counter = millis();
    }
    else if (millis() - counter > 10) {
      counter = 0;
      DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
      state = WAIT_LO;
      key = 0;
      bitn = 7;
    }
  }

  else if (state == READ) {      // read key message (8 bits)
    if ((PINB & BITMASK_A500CLK) != 0) {
      if (bitn--) {
        key += ((PINB & BITMASK_A500SP) == 0) << (bitn); // key code (add bits 0...6)
        state = WAIT_LO;
      }
      else {  // read last bit (key down)
        keydown = ((PINB & BITMASK_A500SP) != 0); // true if key down
        interrupts();
        state = HANDSHAKE;
        if (key == 0x5F)  fn = keydown; // "Help" key: special function on/off
        else if (key == 0x62) keystroke(0x39, 0x00); // CapsLock
        else {
          if (keydown) {
            // keydown message received
            if (fn) {
              // special function with "Help" key
              if (key == 0x50) keystroke(0x44, 0); // F11
              else if (key == 0x51) keystroke(0x45, 0); // F12
              else if (key == 0x5A) keystroke(0x53, 0); // NumLock
              else if (key == 0x5B) keystroke(0x47, 0); // ScrollLock
              else if (key == 0x02) keystroke(0x14, 0x40); // @
              else if (key == 0x04) keystroke(0x35, 0x02); // ÃÆ'ƒÆ’ÃÆ'¢â‚¬Å¡ÃÆ'ƒâ€šÃÆ'‚°
            }
            else {
              if ((key == 0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35, 0x00); // ^ (with shift)
                else if (key == 0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30, 0x40); else keystroke(0x35, 0x20); // ~,`
                else if (key == 0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64, 0x40); else keystroke(0x2D, 0x40); // |,\
                else if (key == 0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24, 0x40); else keystroke(0x25, 0x40); // {,[
                else if (key == 0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27, 0x40); else keystroke(0x26, 0x40); // },]
              else if (key < 0x68) keypress(key);  // Code table
            }
          }
          else {
            // keyrelease message received
            if (key < 0x68) keyrelease(key);  // Code table
          }
        }
      }
    }
  }

  else if (state == WAIT_LO) { // waiting for the next bit
    if ((PINB & BITMASK_A500CLK) == 0) {
      noInterrupts();
      state = READ;
    }
  }
}


void keypress(uint8_t k) {

  if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
  else {
    for (uint8_t i = 0; i < 6; i++) {
      if (_keyReport.keys == 0) {
        _keyReport.keys = ktab[key];
        break;
      }
    }
  }
  HID_SendReport(2, &_keyReport, 8);
}


void keyrelease(uint8_t k) {

  if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
  else {
    for (uint8_t i = 0; i < 6; i++) {
      if (_keyReport.keys == ktab[key]) _keyReport.keys = 0;
    }
  }
  HID_SendReport(2, &_keyReport, 8);
}


void keystroke(uint8_t k, uint8_t m) {

  unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
  for (uint8_t i = 0; i < 6; i++) {
    if (_keyReport.keys == 0) {
      _keyReport.keys = k;
      _keyReport.modifiers = m;
      HID_SendReport(2, &_keyReport, 8);
      _keyReport.keys = 0;
      _keyReport.modifiers = memomodifiers; // recover modifier state
      HID_SendReport(2, &_keyReport, 8);
      break;
    }
  }
}
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: CypherXG on Jan 27, 2017, 06:58 am
Mhhhh.
I don't have this Delay.
Do you have an Error in your Code:
ÃÆ'ƒÆ’ÃÆ'¢â‚¬Å¡ÃÆ'ƒâ€šÃÆ'‚°


This is my Code.
It is a German Layout:
Code: [Select]

#include <Keyboard.h>
#define HID_SendReport(id,data,len) HID().SendReport(id,data,len) // IDE 1.6.9
    #define BITMASK_A500CLK 0b00010000    // IO 8
    #define BITMASK_A500SP  0b00100000    // IO 9
    #define BITMASK_A500RES 0b01000000    // IO 10
    #define BITMASK_JOY1    0b10011111    // IO 0..5,7
    #define BITMASK_JOY2    0b11110011    // IO A0..A5   
    #define SYNCH_HI        0
    #define SYNCH_LO        1
    #define HANDSHAKE       2
    #define READ            3
    #define WAIT_LO         4
    #define WAIT_RES        5

    KeyReport _keyReport;
    uint32_t counter = 0;
    uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn,keydown, ktab[0x68]={
      // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
      0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
      // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
      0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
      // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
      0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
      // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
      0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
      // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
      0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
      // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
      0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
      // modifiers: Shift left, Shift right, -, Win left, Crtl left, Ctrl right, Alt left, Alt right
      //0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0x08, 0x10

      0x02, //SHIFT-LINKS
0x20, //SHIFT-RECHTS
0x00,
0x01, //LINKS-CTRL
0x04, //RECHTS-ALT
0x40, //LINKS-AMIGA
0x08, //LINKS-ALT
// 0x9F,
0x80, //RECHTS-AMIGA
    };

    void setup() {
      // Joystick 1 (Port D)
      DDRD = ~BITMASK_JOY1; // direction INPUT
      PORTD = BITMASK_JOY1; // activate PULLUP
     
      // Joystick 2 (Port F)
      DDRF = ~BITMASK_JOY2; // direction INPUT
      PORTF = BITMASK_JOY2; // activate PULLUP

      // Keyboard (Port B)
      DDRD = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT
    }


    void loop() {
      // Joystick 1
      Joy = ~PIND & BITMASK_JOY1;
      if (Joy != MemoJoy1) {
        HID_SendReport(3, &Joy, 1);
        MemoJoy1 = Joy;
      }

     // Joystick 2
      Joy = ~PINF & BITMASK_JOY2;
      if (Joy != MemoJoy2) {
        HID_SendReport(4, &Joy, 1);
        MemoJoy2 = Joy;
      }
     
      // Keyboard
        if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {   // Reset
        interrupts();
        keystroke(0x4C,05);        // CTRL+ALT+DEL
        fn=0;
        state=WAIT_RES;
      }
     
      else if (state==WAIT_RES) {   // Waiting for reset end
        if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
      }
     
      else if (state==SYNCH_HI) {   // Sync-Pulse HI
        if ((PINB & BITMASK_A500CLK)==0) state=SYNCH_LO;
      }

      else if (state==SYNCH_LO) {   // Sync-Pulse LOW
        if ((PINB & BITMASK_A500CLK)!=0) state=HANDSHAKE;
      }
     
      else if (state==HANDSHAKE) {  // Handshake
        if (counter==0) {
          DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
          PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
          counter=millis();
        }
        else if (millis()-counter>10) {
          counter=0;
          DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
          state=WAIT_LO;
          key=0;
          bitn=7;
        }
      }
     
      else if (state==READ) {        // read key message (8 bits)
        if ((PINB & BITMASK_A500CLK)!=0) {
          if (bitn--){
            key+=((PINB & BITMASK_A500SP)==0)<<(bitn); // key code (add bits 0...6)
            state=WAIT_LO;
          }
          else {  // read last bit (key down)   
            keydown=((PINB & BITMASK_A500SP)!=0); // true if key down
            interrupts();
            state=HANDSHAKE;
            if (key==0x5F)  fn=keydown;  // "Help" key: special function on/off
            else if (key==0x62) keystroke(0x39,0x00);  // CapsLock
            else {
              if (keydown){
                // keydown message received
                if (fn) {
                  // special function with "Help" key
                  if (key==0x50) keystroke(0x44,0);  // F11
                  else if (key==0x51) keystroke(0x45,0);  // F12
                  else if (key==0x5A) keystroke(0x53,0);  // NumLock
                  else if (key==0x5B) keystroke(0x47,0);  // ScrollLock
                  else if (key==0x02) keystroke(0x14,0x40);  // @
                  else if (key==0x04) keystroke(0x35,0x02);  // °
                }
                else {
                  if ((key==0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35,0x00);  // ^ (with shift)
                  else if (key==0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30,0x40); else keystroke(0x35,0x20); // ~,`
                  else if (key==0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64,0x40); else keystroke(0x2D,0x40); // |,\
                  else if (key==0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24,0x40); else keystroke(0x25,0x40); // {,[
                  else if (key==0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27,0x40); else keystroke(0x26,0x40); // },]
                  else if (key < 0x68) keypress(key);  // Code table
                }
              }
              else {
                // keyrelease message received
                if (key < 0x68) keyrelease(key);  // Code table
              }
            }
          }
        }
      }
     
      else if (state==WAIT_LO) {   // waiting for the next bit
        if ((PINB & BITMASK_A500CLK)==0) {
          noInterrupts();
          state=READ;
        }
      }
    }
       

    void keypress(uint8_t k) {
     
      if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
      else {
        for (uint8_t i=0; i<6; i++) {
          if (_keyReport.keys[i] == 0) {
             _keyReport.keys[i] = ktab[key];
             break;
          }
        }
      }
      HID_SendReport(2,&_keyReport,8);
    }


    void keyrelease(uint8_t k) {

      if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
      else {
        for (uint8_t i=0; i<6; i++) {
          if (_keyReport.keys[i] == ktab[key]) _keyReport.keys[i] = 0;
        }
      }
      HID_SendReport(2,&_keyReport,8);
    }


    void keystroke(uint8_t k, uint8_t m) {
     
      unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
        for (uint8_t i=0; i<6; i++) {
          if (_keyReport.keys[i] == 0) {
             _keyReport.keys[i] = k;
             _keyReport.modifiers = m;
             HID_SendReport(2,&_keyReport,8);
             _keyReport.keys[i] = 0;
             _keyReport.modifiers = memomodifiers; // recover modifier state
             HID_SendReport(2,&_keyReport,8);
             break;
          }
        }
    }

I also disabled the CTRL+ALT+DEL function, because it locked Windows an Softreset an Raspberry.

I'm also searching a Hex Code Key for "Win Menu" on the Keyboard.
This is needed to Reset the UAE4ARM Emulator.

Greets Markus
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: JensBe on Jan 29, 2017, 11:02 pm
Thanks Markus for reply,

no, I don´t think this is an error, the syntax seems to be proper. These are only special signs in "Pseudocode". It seems that this error comes after a period of time. After a coldstart of my PC everything seems to be ok, but after a while this delay comes. Is it mabe because of elecromagnetic radiation? Maype the fan? Do I have to shield the leonardo?

In former µC Projects ith AVRs I had to do this....
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: CypherXG on Jan 31, 2017, 08:29 am
Mhhh...delay.....after a period of time.....

Is your A500 Keyboard really ok?
It may also be a hardware error from the Keyboard.
Do you try an other Keyboard?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Piglet on Apr 03, 2017, 04:37 pm
Thanks for this :)

I struggeled a while to get this to compile...

I had to get an older version of Arduino IDE to get this to compile, and I had to include the keyboard library.


This info should be in the initial post imho: The version of the IDE used to compile the code, and more detailed info on libraries and what to do with hid library for joysticks.


I soldered headers to a Micro Pro and got that to work flawlessly. It works just like a Leonardo, but it is alot smaller, and can fit inside most devices to convert them to USB-HID.


To free up any cycles and optimize for my usage, I removed the joystick parts of the code. I don't know if it has any effect on reliability/performance, but both the the main loop and the rest of the code is smaller now...


I did this since I'll just break out, and use USB ports for joysticks and joypads on my "Amiga 500PI".


I've been having a read in those pages linked in an earlier post, but I couldn't match the keycodes to those in the sketch, or those in the library, and I've just been scratching my head.


Since I'm still a noob, I would love an explanation on how this code interfaces with the keyboard and gets/reads scancodes and how/where the translation is done.


Would love to learn more and if possible get the scancodes both directly from the keyboard before translation, and the result of the translation, to the serial console


Maybe in time I could customize/optimize the keyboard library for my Amiga usage.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: mrpromo on Apr 05, 2017, 04:20 pm
Hi struggling here as first port was 2012 and been trying for hours now  ,

any advice would be great  thank you 
as a foot note I can only get to compile in older version but doesn't seem to work

thank you
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: mrpromo on Apr 05, 2017, 04:59 pm
update all sorted was me being an idiot
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: cptkrabbe on Apr 19, 2017, 07:21 pm
Oh my god... this is actually working. I am writing this with a a500 keyboard. I never even owned an arduino until 1 hour ago. this took me 5 minutes to set up. I can´t believe it. You guys rock.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Apr 20, 2017, 11:05 pm
Awesome! I still have a few A1000 keyboards. I'm thinking of making an Amiga laptop using the A1000 keyboard and a Raspberry Pi 3 with UAE and Amiga Forever for the ROMs and disk image. Well, actually I have a disk image from using Amiga Forever since, well, long ago.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DrRemulak on Jul 16, 2017, 10:10 pm
Attached is my version of the sketch for use with an Amiga Emulator on Raspberry Pi, "Amibian". The RasPi fits very easily into an A500 case with the motherboard/floppy removed, so I wanted to use the stock A500 keyboard.
I loaded this sketch into the Leonardo with the web editor, and it works. For testing, I actually used an Amiga 2000 keyboard with only 4 pins. It is missing the Reset pin, so I had to comment out the CTRL ALT DEL code otherwise I get a constant signal of soft reset from the Leonardo. I don't really need this function for the emulator anyway. It was trial-and-error trying to find the pinout for the A2000 keyboard. This might save someone time:
KBD=ARD
Pin1=GND
Pin2=5v
Pin3=Pin8
Pin4=Pin9

I set my help key and numpad up for use with the emulator. I didn't need all the extra navigation stuff, so I mapped the "Help" key to be F12 for easy access to the emulator GUI, and I set the NumL and ScrL as the primary function for those keys. Also added a LED on pin 5 to light when NumL is active (not sure if I will wind up using it, but someone may).
I found a chart with Amiga keycodes here: http://wiki.amigaos.net/wiki/Keymap_Library
Scroll down to the "Raw Key Table", and look at the 3rd Column "USB Code". Substitute the first two digits with a 0x (Ex: 0034 needs to be 0x34 in your code).
Thanks to the OP, et. all.

Code: [Select]
#include <Keyboard.h> // FOR NEWEST IDE 1.6.9
#define HID_SendReport(id,data,len) HID().SendReport(id,data,len) // IDE 1.6.9

#define BITMASK_A500CLK 0b00010000    // IO 8
#define BITMASK_A500SP  0b00100000    // IO 9
#define BITMASK_A500RES 0b01000000    // IO 10
#define BITMASK_JOY1    0b10011111    // IO 0..4,6
#define BITMASK_JOY2    0b11110011    // IO A0..A5   
#define SYNCH_HI        0
#define SYNCH_LO        1
#define HANDSHAKE       2
#define READ            3
#define WAIT_LO         4
#define WAIT_RES        5

KeyReport _keyReport;
uint32_t counter = 0;
uint8_t Joy, MemoJoy1, MemoJoy2, state, bitn, key, fn,keydown, ktab[0x68]={
  // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
  0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31,    0, 0x62,
  // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
  0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0   , 0x59, 0x5A, 0x5B,
  // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
  0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0,    0x5C, 0x5D, 0x5E,
  // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
  0x64, 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38,    0, 0x63, 0x5F, 0x60, 0x61,
  // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
  0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C,    0,    0,    0, 0x56,    0, 0x52, 0x51, 0x4F, 0x50,
  // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
  0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43,    0,    0, 0x54, 0x55, 0x57,    0,
  // modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Win (amiga) left, Ctrl (amiga)right
  0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0xE3, 0xE7
};

void setup() {
  // Joystick 1 (Port D)
  DDRD = ~(BITMASK_JOY1); // direction INPUT
  PORTD = BITMASK_JOY1; // activate PULLUP
 
  // Joystick 2 (Port F)
  DDRF = ~(BITMASK_JOY2); // direction INPUT
  PORTF = BITMASK_JOY2; // activate PULLUP

  // Keyboard (Port B)
  DDRB = ~(BITMASK_A500CLK | BITMASK_A500SP | BITMASK_A500RES);  // direction INPUT

  //numlock LED
  pinMode(5, OUTPUT);
}


void loop() {
  // Joystick 1
  Joy = ~PIND & BITMASK_JOY1;
  if (Joy != MemoJoy1) {
    HID_SendReport(3, &Joy, 1);
    MemoJoy1 = Joy;
  } 

// Joystick 2
  Joy = ~PINF & BITMASK_JOY2;
  if (Joy != MemoJoy2) {
    HID_SendReport(4, &Joy, 1);
    MemoJoy2 = Joy;
  } 
 
  // Keyboard

//   if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {   // Reset
//    interrupts();                   //this doesn't work with 4 pin A2000 keyboards
//    keystroke(0x4C,05);        // CTRL+ALT+DEL
//    fn=0;
//    state=WAIT_RES;
//  }
 
//  else if (state==WAIT_RES) {   // Waiting for reset end
//    if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
//  }
//  else if
 
   if (state==SYNCH_HI) {   // Sync-Pulse HI
    if ((PINB & BITMASK_A500CLK)==0) state=SYNCH_LO;
  }

  else if (state==SYNCH_LO) {   // Sync-Pulse LOW
    if ((PINB & BITMASK_A500CLK)!=0) state=HANDSHAKE;
  }

  else if (state==HANDSHAKE) {  // Handshake
    if (counter==0) {
      DDRB |= BITMASK_A500SP;   // set IO direction to OUTPUT
      PORTB &= ~BITMASK_A500SP; // set OUTPUT to LOW
      counter=millis();
    }
    else if (millis()-counter>10) {
      counter=0;
      DDRB &= ~BITMASK_A500SP;   // set IO direction to INPUT
      state=WAIT_LO;
      key=0;
      bitn=7;
    }
  }
 
  else if (state==READ) {        // read key message (8 bits)
    if ((PINB & BITMASK_A500CLK)!=0) { 
      if (bitn--){
        key+=((PINB & BITMASK_A500SP)==0)<<(bitn); // key code (add bits 0...6)
        state=WAIT_LO;
      }
      else {  // read last bit (key down)   
        keydown=((PINB & BITMASK_A500SP)!=0); // true if key down
        interrupts();
        state=HANDSHAKE;
        if (key==0x62) keystroke(0x39,0x00);  // CapsLock
        else {
          if (keydown){
            // keydown message received------
              if (key==0x5A) {
                keystroke(0x53,0); // Num lock active without modifier
                if (digitalRead(5)) // Num lock LED on Pin
                  digitalWrite(5, LOW);
                else
                  digitalWrite(5, HIGH);
              }
              else if (key==0x5B) keystroke(0x47,0); // Scroll lock active without modifier
              else if (key==0x5F) keystroke(0x45,0); // Help is F12 to bring up UAE emulator interface
              else if (key < 0x68) keypress(key);  // All remaining keys via Code table
          }
          else {
            // keyrelease message received
            if (key < 0x68) keyrelease(key);  // Code table
          }
        }
      }
    }
  }
 
  else if (state==WAIT_LO) {   // waiting for the next bit
    if ((PINB & BITMASK_A500CLK)==0) {
      noInterrupts();
      state=READ;
    }
  }
}
   

void keypress(uint8_t k) {
 
  if (k > 0x5f) _keyReport.modifiers |= ktab[key];  // modifier
  else { 
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = ktab[key];
         break;
      }
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keyrelease(uint8_t k) {

  if (k > 0x5f) _keyReport.modifiers &= ~ktab[key];  // modifier
  else { 
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == ktab[key]) _keyReport.keys[i] = 0;
    }
  }
  HID_SendReport(2,&_keyReport,8);
}


void keystroke(uint8_t k, uint8_t m) {
 
  unsigned short memomodifiers = _keyReport.modifiers; // save last modifier state
    for (uint8_t i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0) {
         _keyReport.keys[i] = k;
         _keyReport.modifiers = m;
         HID_SendReport(2,&_keyReport,8);
         _keyReport.keys[i] = 0;
         _keyReport.modifiers = memomodifiers; // recover modifier state
         HID_SendReport(2,&_keyReport,8);
         break;
      }
    }
}
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: JensBe on Nov 25, 2017, 11:20 pm
Sorry, another question.
My former problem is solved, the controller of the keyboard itself was defect.
Now I added Joystick Ports to the Leonardo, but I don´t know how to configure them under WINUAE.
Can anybody help?

Kind regards

Jens
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: zyonee on Dec 25, 2017, 04:13 pm
This thing is working like a charm!

Typing this on an A500 keyboard, that's really a wonderful feeling. Thanks, guys!

Got a question. In earlier versions of the Arduino IDE, one could simply add stuff to HID.cpp, but in the later versions, it seems like this has been abstracted into separate places, such as Keyboard.h and Mouse.h. Any ideas where to add the Atari DB9 joystick information nowadays?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yorgle on Jan 12, 2018, 04:33 pm
Is there anything special that needs to be done to interface this with an A1000 keyboard? I have it running on my Leo, working with an A500 keyboard, but my A1000 keyboard is just outputting garbage.  I got it to send ok data once, but generally, it just spews random characters.   

I do notice a difference electrically in the A500 and A1000 schematics between the keyboard connection and the 8250... (not including the reset circuit of course.)

Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Jan 14, 2018, 07:19 pm
The A1000 keyboard is the same electronically as the A2000, A3000, and A4000 keyboards. It has been a while, but it seems to me the A500 keyboard is a little different.

Do you have a way to test your A1000 keyboard to confirm it is operating correctly?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yorgle on Jan 14, 2018, 08:41 pm
Yeah. I'll double check it with my A1000.  I did notice that with the A1000 keyboard, I needed an external power supply for it (the Arduino kept on browning-out) and also if i touched the data/clock pins, it would generate more noise.

A couple things I'm going to try (and will report back here afterwards, to document it)



But yeah, the pullups in the A500 schematic are different than the A1000 (4.7k vs 10k) so that, combined with the RJ-12 cable could be pushing the voltage levels down to the point that the Ardy can't quite read the right levels...
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yorgle on Jan 15, 2018, 06:59 am
Okay.  I just tried a whole bunch of things...

Just tried two A1000 keyboards on my A1000, and both work perfectly.  Also tried them on my A500 with an adapter I made, and they work as-expected there too. I measured the output from the keyboards.  The A500 keyboard shows a 0 - 2.8v range on its clock and data lines. The A1000 keyboard shows a 0 - 1.9v range on the same lines.  I did connect wiring directly to the A1000 keyboard internally as well, and it showed no difference nor improvement.

So I think I need to build some sort of voltage level converter to boost the A1000 keyboard's signaling range.

Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Jan 16, 2018, 08:21 pm
How did you measure the output voltages? Oscilloscope?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yorgle on Jan 17, 2018, 04:25 am
Yes. on a scope. Although I just got a better one on loan from a friend and I've found something interesting... 

The signalling looks the same (Since i've run the A1k keyboard on my A500, i know it's compatible) however, it's MUCH quicker.

Clock pulses on the A500 keyboard are around 50us.  On the A1000 keyboard, they're about 25us, so this code won't work as it is.  I'm looking into optimizing it.

For the A1k keyboard, you also will probably need to clean up the signal by throwing some external pullup resistors.  I'm using 3.3k pullups (as per the A1k schematic) and it squares out the A1000's signal pretty well. The A500 keyboard works fine with these pullups as well.

Updated code soonish... :)  Although I may end up rewriting it...

(and the voltage measurement was wrong. they're both rock solid around 4v)

https://twitter.com/yorgle/status/953442116306456576
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: hanker on Feb 17, 2018, 11:09 am
Hello @all!

As I'm also using a German keyboard layout, I noticed two errors in CypherXG's code.

[...]
Code: [Select]

                  if ((key==0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35,0x00);  // ^ (with shift)
                  else if (key==0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30,0x40); else keystroke(0x35,0x20); // ~,`
                  else if (key==0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64,0x40); else keystroke(0x2D,0x40); // |,\
                  else if (key==0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24,0x40); else keystroke(0x25,0x40); // {,[
                  else if (key==0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27,0x40); else keystroke(0x26,0x40); // },]
                  else if (key < 0x68) keypress(key);  // Code table

Has to be replaced with

Code: [Select]

                  if ((key==0x2B) && (_keyReport.modifiers & 0x22)) keystroke(0x35,0x00);  // ^ (with shift)
                  else if (key==0x00) if (_keyReport.modifiers & 0x22) keystroke(0x30,0x40); else keystroke(0x32,0x02); // ~,'
                  else if (key==0x0D) if (_keyReport.modifiers & 0x22) keystroke(0x64,0x40); else keystroke(0x2D,0x40); // |,\
                  
                  else if (key==0x5A) if (_keyReport.modifiers & 0x22) keystroke(0x24,0x40); else keystroke(0x25,0x40); // {,[
                  else if (key==0x5B) if (_keyReport.modifiers & 0x22) keystroke(0x27,0x40); else keystroke(0x26,0x40); // },]
                  else if (key < 0x68) keypress(key);  // Code table


This works with the current WebIDE (Web App Version - 3.0.8 ). Note the additional free line behind the definition of " |,\ " (otherwise the next line will be ignored) and the corrected keystroke for " ~,' " (was actually " ~,° ").


Also, I'm experiencing weird behaviour when using "Ctrl+Amiga+Amiga", regardless of activating the reset code or not. Every time, "Ctrl-Amiga+Amiga" is pressed, the keyboard seems to be stuck at holding "Ctrl+Amiga". I verified this a lot of times, after "Ctrl+Amiga+Amiga" p.e. pressing "d" opens a new virtual desktop in Windows 10. After pressing each of the three keys once (and alone), everything is as normal.

"Ctrl+Amiga" (one, not both Amiga keys) does not produce this "stuck keys" behaviour.


Anyone an idea for a solution?


Greetings from Germany

René
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yorgle on Feb 23, 2018, 04:07 am
You're probably seeing that behavior with Ctrl-A-A because you get most of those key-down messages (at least for whatever the first two keys that are pressed, and then the keyboard controller resets itself and toggles the RESET line.  You never actually get the key up messages.  maybe.  I haven't fully figured out the capabilities of the code provided here...



I'm working on new firmware which has slightly different wiring, to improve compatibility with A1000's speed and the A2000/3000 keyboard behaviors.  -- Clock and data connect to pins D0 and D1 instead of D8 and D9.  I am not yet ready to share this, but i will post on this thread when i am. 

A2000/3000 have a different reset (ctrl-a-a) behavior than the A500..  You can simulate this by disconnecting Q1 from the circuit on your keyboard's controller.  It won't be necessary for mine...
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Phoenix2003 on Mar 10, 2018, 03:23 am
Hi everyone, I'm new user.
I have a problem I would like to transform the A500 USB keyboard with Arduino Leonardo pro micro, but I do not know how to connect someone has some picture or scheme on where the A500 connector should be placed?
Thanks to all of you, I hope I have explained myself well.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Mar 13, 2018, 05:23 pm
It is in the first post:
https://forum.arduino.cc/index.php?topic=139358.0


From that post:

Code: [Select]

Keyboard   Leonardo
Connector  IO          

1   KBCLK   8
2   KBDATA  9
3   KBRST   10
4   5v      5v
5   NC
6   GND     GND
7   LED1    5V
8   LED2    -
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Phoenix2003 on Mar 14, 2018, 01:57 am
Hi Polymorph thank you for reply  :)
I'm just starting, which files should I upload then on to Arduino Leonardo pro micro in order to work?

if I purchase Arduino Leonardo pro micro with ATMEGA32U4, should it be all right?

thank you

I attach the scheme of the two models, according to you and correct?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: patts75 on Mar 22, 2018, 07:16 am
First of all. Thanks to all involved in this project! With minimal soldering skills and knowlage in Arduino i managed to make this happen. So happy to finaly get my project going and resurrect my A500+ from the dead (broken motherboard).

I used a Arduino Leonardo pro micro clone for this project.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: patts75 on Mar 22, 2018, 07:21 am
Hi Polymorph thank you for reply  :)
I'm just starting, which files should I upload then on to Arduino Leonardo pro micro in order to work?

if I purchase Arduino Leonardo pro micro with ATMEGA32U4, should it be all right?

thank you

I attach the scheme of the two models, according to you and correct?
I've used the same board and your scheme for the connection. And it works. :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Phoenix2003 on Mar 24, 2018, 02:54 am
I've used the same board and your scheme for the connection. And it works. :)
Thank you  :smiley-wink:

how did you program it?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: patts75 on Mar 28, 2018, 11:24 am
Thank you  :smiley-wink:

how did you program it?
I used @DrRemulak script on page 5 (post #60) and the latest IDE. And it works like a charm with Amibian. No joystick DSubs wired up just yet. But i'll try that out later.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yserra on Jun 30, 2018, 04:06 pm
It works! I'm typing this text from my Amiga 1000 keyboard. I first experimented the same issues as Yorgle did (garbage text with an A1000 keyboard, as he mentioned on comment #63), but it appears the issue didn't come from a presumed specific clock speed (comment #68), it just came from a faulty adapter, making noise in the signal. Here is what I did to make it work:

- Plugging the RJ9 male jack from the Amiga 1000 keyboard cordon into a regular RJ45 CAT5e female connector

- Wiring pins 3, 4, 5 and 6 from the RJ45 to the pins 5v, 8, 9, GRND respectively on the Arduino Leonardo with CAT5e single-strand network cable (I think THIS PARTICULAR kind of cable makes it works without making any noise on the signal)

The wires are not soldered. They are crimped on the RJ45 side and have the right width for connecting them directly into the Arduino Leonardo headers.

My keyboard is a French version (ISO/European layout), and I use the code from DrRemulak (comment #60).

EDIT: the controller on my A1000 keyboard with ISO layout is a MOS 6570-36, the same one found on the other Amiga keyboard (500, 2000, 3000, 4000). I guess it's because this Amiga is the second generation of A1000, the PAL version, launched in Europe in 1986, just before the A500 and A2000. Yorgle seems to have an original A1000 NTSC, produced in 1985. On this earlier model the controller is a MOS 6570-33. Maybe that explains the incompatibility he experimented with the code we discuss here.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: Boss00 on Jul 01, 2018, 02:04 am
Hey guys, I'm new to the forum. sorry for my english.
I built an a500, inside I mounted a toshiba portege r830,
I adapted the a500 keyboard with arduino pro micro 5v. when windows started system everything works perfectly. often I use the bios to boot from cd ... every time I have to connect an external usb keyboard, because of the problem of hid leonardo recognition ... I also read a certain NICOHOOD who released patches in about. but let's say that I'm very good with wired electronics, and the electronics programmed for me is a bit difficult to understand ... someone would know how to help me about the problem of bios with an example to apply, and I would be grateful. :)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DrRemulak on Jul 27, 2018, 05:19 am
Here is code for early A1000 keyboards with the MOS 6570-33/328191-01 keyboard controller IC! My tests have all been great so far.

I also figured out the reboot issue! The A1000 keyboard does not have a separate RESET signal wire, it only has 4 wires on the connector. Also the 4-wire reboot code in this sketch can be applied to my previous A2000 code to make it work on 4-wire A2000 keyboards.


Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DrRemulak on Jul 29, 2018, 02:33 am
And here is a version for A2000 4-wire keyboards. I have not tried it on A500/A2000 with extra Reset wire, but it very well may work.

Annoyingly, my 4-wire A2000 keyboard (and possibly others), ignore the first keystroke. What happens is the Leonardo waits for the first keystroke to sync with the keyboard, and during that sync phase misses the keypress. However it does get the key release, so I added code there to process it as a press-and-release. Because of that, held-down modifiers (shift, ctrl, alt) are ignored. I did get CTRL+Amiga+Amiga to work as the first keystroke though.


Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DrRemulak on Aug 19, 2018, 09:38 pm
I am a totally noob in Arduino,
i am trying program a Arduino Pro Micro with this code to use a spanish A2000 keyboard on a Raspberry Pi , when i connect the Arduino on the PC USB connector, the computer think that i has press CTRL+ALT+DEL,
Whats append?
Is problem of my Arduino Pro Micro?
I am doing something wrong?
Which code are you using? The original code by the original poster has this issue, but not my modified code. See the code attached to my latest posts.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: DrRemulak on Aug 31, 2018, 04:32 am
I have discovered one more bug. The CTRL-ALT-DEL command is being sent on bootup and connection. I missed it because uploading the sketch and the reconnection/restart of the Arduino did not cause it. It is only when I boot up a PC, or when I plug the Arduino in to USB that the this happens. I discovered that I have no need for the CTRL+A+A reboot functionality, so I simply commented out the two lines that send it. They must be both commented out to avoid this issue. Not sure why both are being executed at connection, I will revisit this later.
 
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: belfers on Oct 02, 2018, 05:38 am
This is the keyboard mapping (with wire colors) that worked for my Amiga 500 …

Amiga 500 wire harness        Arduino pin
--------------------------------------------------

1   KBCLK   (bronze wire)          9
2   KBDATA (black wire)            8
3   KBRST   (red wire)              10
4   5v         (orange wire)          5v
5   NC
6   GND      (green wire)           GND
7   LED1     (blue wire)              5v      
8   LED2

Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: witchmaster on Oct 05, 2018, 09:09 am
First of all, thank you @Olaf and @DrRemulak for the work on this, much appreciated! :)

Here is my version based on the latest 4-wire keyboard code by @DrRemulak. I included new code for joysticks based on the code by @Olaf but now there is no need to add HID descriptions in other files.

This version works fine on the MiSTer (https://github.com/MiSTer-devel/Main_MiSTer/wiki) (Terasic DE10-Nano FPGA development board) with the Amiga core (joysticks included). I tested a CDTV keyboard and a A500 keyboard, the A500 keyboard works fine even if the RESET pin is not connected.

On this version CLOCK goes to pin 8 and DATA to pin 9, confusing. I included connection diagrams for joysticks and various Amiga keyboards in the code.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: retronewb on Oct 27, 2018, 09:28 pm
Hi,

I am looking to use an Amiga 500 keyboard in a project I am working on.  I am wondering if it would be possible to alter this code to work as a serial keyboard, All I am looking to do is take the keystrokes from the Amiga keyboard and display them in the serial console.

I would be using an Arduino Nano instead of a Leonardo.

Any help appreciated.

Thanks.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yserra on Jan 06, 2019, 08:12 pm
Hi all,

I noticed the Amiga keys don't work correctly with DrRemulak's script. The lines:

// modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Amiga left, Amiga right
  0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0xE3, 0xE7

Should be changed (from Olaf's original script) to:
// modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Win (amiga) left, Ctrl (amiga) right
  0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0x08, 0x10

Or if you prefer having a Win Right on Amiga Right key, It should be:
// modifiers: Shift left, Shift right, -, Crtl left, Alt left, Alt right, Win (amiga) left, Win (amiga) right
  0x02, 0x20, 0x00, 0x01, 0x04, 0x40, 0x08, 0x80
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: gavinsaxby on Nov 11, 2019, 11:29 am
So I realise this is a very old post indeed now, but I've just tried to get this working with an Amiga 3000 keyboard and haven't got anywhere. If I try it on a PC then I just keep on getting the ctrl+alt+delete sent to the PC. If I try it on the Mac then it just gives out this constantly:

[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~[3;5~

As far as I know the keyboard works OK, but since I don't have a real Amiga knocking around any more I can't actually check it. I can get it onto my scope this evening and start to look at the data/clock, but I was wondering if anyone has tried it with an A3000 keyboard before.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yserra on Jan 06, 2020, 11:16 am
@gavinsaxby: yes, the Amiga 3000 keyboard is exactly the same as the last A500/A2000/A4000 ones (and has the same controller as early A1000/A500/A2000 ones too). I suspect you mixed the connections. Here is the diagram :

Code: [Select]

// A2000/A3000 ---------
// Keyboard   Leonardo
// Connector  IO 
// 1 KBCLK    8
// 2 KBDATA   9
// 3 NC       -
// 4 GND      GND
// 5 5V       VCC (5V)
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yserra on Jan 06, 2020, 11:43 am
To all of you who arrived here to connect an Amiga 500/1000/2000/3000/4000 keyboard to an USB port on a modern PC/Mac/Raspberry Pi/whatever computer:

The Olaf-DrRemulak Arduino Leonardo script discussed here is quite obsolete now, since it missed the simpler functions from the Keyboard.h Arduino library, that are especially done for the purpose to convert old keyboards to USB ones.

Here is attached a better script from Janne Lof (I can't find anymore its original link on Internet, sorry).

I confirm this one works well with my A1000 keyboard and should work with all other Amiga keyboards with a controller onboard (so, all Amiga keyboards except the ones from A600 and A1200). I added a 'delay(300)' in the Caps Lock handling subroutine to make the caps lock comptatible with MacOS computers (and it still works with other computers).

Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: herregaarden on Jan 12, 2020, 08:41 pm
Thank you yserra, this works great on my A500 keyboard with a leonardo. Could never get the older scripts to work properly.
The only thing i can't get working is the 2 joystick ports, i have tried with retropie and fsuae on linux, but i can not see the ports
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: polymorph on Feb 04, 2020, 06:16 pm
That's awesome! I would like to build an Amiga laptop using a Raspberry Pi, and it will be great to be able to use an actual Amiga keyboard. Of which I have many.
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: fidelware on Aug 02, 2020, 08:29 am
Hello, first of all thank the people who have made this project possible.  has someone designed a STL case for PRINT it?
Title: Re: AMIGA 500/1000/2000 Keyboard Interface
Post by: yanluowang_666 on Sep 07, 2020, 08:23 pm
Hello,

I wanted to do the amiga keyboard interface with one arduino pro micro.
I made the pcb and bought all the components. I used @yserra code (sketch_clavier_amigav3.I no", but when I insert the code inside the arduino software, I always have error on the code. If someone can help me?

For more information, i did this :
https://www.pcbway.com/project/shareproject/Amiga_2000___3000___500_Keyboard_USB_adapter.html
I ordered pcb and all components.