Author Topic: Is there any recent project to connect a PC (PS/2) keyboard to the CPC?  (Read 19519 times)

0 Members and 1 Guest are viewing this topic.

Offline gerald

  • 6128 Plus
  • ******
  • Posts: 1.130
  • Liked: 812
Thanks, Gerald :) Actually, it did not help, but while adding the resistor net, I did realize I have completely ignored blocking capacitors. I have added one 470uF across the PS/2 keyboard power, and 100nF across the ATTiny and HCT138 power pins.
Now one key press generates just one letter on the screen, however, it's a wrong letter: F produces D, B produces C etc etc :) I believe I have shifted the keyboard rows by one. Could you possibly tell me what AY pin should go to what ATTiny pin? The CPC schematics I have uses X1-X8 for the AY pins, while your schematics uses X0-X7. I assumed AY X1 corresponds to your X0, but it doesn't seem to be the case. Thanks!
According to the key swap, it looks more like an error on the line connection from the PPI to the uC (L[3:0] on the schematics).

Offline zrusavpt

  • CPC464
  • **
  • Posts: 12
  • Country: de
  • Liked: 2
Thanks, Gerald. I am reasonably sure the connection corresponds to the schematic, but just in case:
PPI pin 14 goes to ATTiny pin 2
PPI pin 15 goes to ATTiny pin 3
PPI pin 16 goes to ATTiny pin 8
PPI pin 17 goes to ATTiny pin 9
Is that correct?

Offline gerald

  • 6128 Plus
  • ******
  • Posts: 1.130
  • Liked: 812
Thanks, Gerald. I am reasonably sure the connection corresponds to the schematic, but just in case:
PPI pin 14 goes to ATTiny pin 2
PPI pin 15 goes to ATTiny pin 3
PPI pin 16 goes to ATTiny pin 8
PPI pin 17 goes to ATTiny pin 9
Is that correct?
That right.
Do you have any other wrong key binding to show.
F -> D and B -> C are indicating a wrong line mapping. F and B are on line 6 but line 7 get activated. Rows are OK.


Offline zrusavpt

  • CPC464
  • **
  • Posts: 12
  • Country: de
  • Liked: 2
Thanks again, Gerald!

I have found better CPC schematic and I agree with you, it looks like the row mapping is wrong. I am constantly getting keys from the next row.
(In my schematics, rows are coming from the 74145 decoder while colums are going to AY).

I have reviewed the source code and my recompiled binary, and I can see that UpdateKeyboard isn't inlined, which is most likely the problem. As CPC scans the keyboard row by row, ATTiny spends too much time processing the interrupt, and outputs the value too late. That means that CPC will pick the value up when reading next row.

I suggest to add the following line before the UpdateKeyboard function:

Code: [Select]
static void UpdateKeyboard(void)  __attribute__ ((always_inline));
That should increase the chance that compiler will actually make the UpdateKeyboard inline.

I didn't test this on a real hardware yet - programming my adapter is a bit complicated (due to SMD components), but I believe this will fix the problem. Sorry for bothering you with that, it was my fault... but at least we can prevent others from doing the same mistake :)

Offline gerald

  • 6128 Plus
  • ******
  • Posts: 1.130
  • Liked: 812
Thanks again, Gerald!

I have found better CPC schematic and I agree with you, it looks like the row mapping is wrong. I am constantly getting keys from the next row.
(In my schematics, rows are coming from the 74145 decoder while colums are going to AY).

I have reviewed the source code and my recompiled binary, and I can see that UpdateKeyboard isn't inlined, which is most likely the problem. As CPC scans the keyboard row by row, ATTiny spends too much time processing the interrupt, and outputs the value too late. That means that CPC will pick the value up when reading next row.

I suggest to add the following line before the UpdateKeyboard function:

Code: [Select]
static void UpdateKeyboard(void)  __attribute__ ((always_inline));
That should increase the chance that compiler will actually make the UpdateKeyboard inline.

I didn't test this on a real hardware yet - programming my adapter is a bit complicated (due to SMD components), but I believe this will fix the problem. Sorry for bothering you with that, it was my fault... but at least we can prevent others from doing the same mistake :)
If the IRQ is not inlined, that could be the problem. The inlined version takes 6.875us, the Z80 requires update in less than 7.4us
Which version of AVRGCC are you using ? I've only tested this code with the latest (oooooold) version of winavr.

Offline zrusavpt

  • CPC464
  • **
  • Posts: 12
  • Country: de
  • Liked: 2
According to "avr-gcc --version":

avr-gcc (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.

I have no clue where did I get it. I used to have WinAVR 20100110, but this is obviously newer.

The non-inlined code has a lot of pushes and pops around the call to UpdateKeyboard(). There's 8 more registers pushed and popped, plus the call and return. If I am counting right, that's 23 more cycles, which is almost 3us, and that definitely gets the interrupt duration over 7.4us.

(It reminds me my attempts to generate VGA video with 25MHz pixel clock :) I was one cycle too long :) )