Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After pressing the NUMLOCK key, there is no response when any key is pressed. #29

Open
goddade opened this issue Jun 6, 2022 · 18 comments

Comments

@goddade
Copy link

goddade commented Jun 6, 2022

I am using version 1.0.9 on esp32.
My keyboard is logitech g100s and it supports usb and ps2.
After pressing any LOCK key, nothing happens when I press any key until I reconnect the keyboard.

Serial output:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:184
load:0x40078000,len:12600
load:0x40080400,len:2724
entry 0x40080594
PS2 Advanced Key Simple Test:
Value AA - Status Bits 0  Code AA
Value 41 - Status Bits 0  Code 41
Value 8041 - Status Bits 80  Code 41
Value 41 - Status Bits 0  Code 41
Value 8041 - Status Bits 80  Code 41
Value 41 - Status Bits 0  Code 41
Value 8041 - Status Bits 80  Code 41
Value 1103 - Status Bits 11  Code 3
Value FA - Status Bits 0  Code FA
@goddade
Copy link
Author

goddade commented Jun 6, 2022

readID works, but typematic and getScanCodeSet stop responding.

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:184
load:0x40078000,len:12600
load:0x40080400,len:2724
entry 0x40080594
Starting BLE work!
Keyboard OK..
49
Read ID code
FA
AB
83
8049
52
Reset
FA
AA
49
Read ID code
FA
AB
83
8049
53
Get Scancode set in use
FA

@techpaul
Copy link
Owner

techpaul commented Jun 6, 2022

So lets start with you have a USB keyboard with a special USB to PS2 adapter. See the pinned issue #23

Note USB 2 in its spec says a device on enumeration can draw up to 500mA, most real PS2 keyboards draw 100 to 200 mA.

Most boards only support from a USB connection 200 to 300 mA on ALL pins and external circuit loads. There are MANY esp32 boards and some operate at 3V3 so you need to have a level translator between board and keyboard that operate on 5V only.

When you do a LOCK key the library toggles the asociated LED ON (or OFF), with typematic and getscancode the processor in the keyboard is probably using more power. This is evidenced by the fact you see lockups. You need to drive your board from an external 5V source to ensure enough current can get to the USB keyboard.

I suspect as soon as these commands occur the CPUsupply is dropping and if you have put 5V to the keyboard that is dropping. Anything can happen then.

This is a function of using a primarily USB keyboard and low power available from a USB only supplied board.

@goddade
Copy link
Author

goddade commented Jun 7, 2022

The keyboard and esp32 use a 5V 3A power adapter, there should be no problem of insufficient power supply.

@techpaul
Copy link
Owner

techpaul commented Jun 7, 2022

You need to check voltage levels at the actual connection to the keyboard, before and after a hang before proceeding further. Check your esp32 board can really hadle 5V GPIO, not 5V tolerant.

Check what actually is happening,

@sam-was-here
Copy link

I have seen the same issue. When ever the the board I'm using try to send anything to the keyboard the board will stop reading new keypresses (the board dont lock up and still it running code). I have only tested this on boards using the SAMD architectures. I used adafruit QT Py SAMD21, Seeeduino XIAO, and Adafruit feather M4 express. I think Its a problem how SAMD (and in your case esp32) boards handles changing pinmodes and how they handle interrupt stuff. I have tested this on maybe 8 different keyboards but I have the problem on all of them, I powered the keyboard from the VIN pin because I was geting power from USB. For all the times testing to get communication from board to keyboard I was using one of the voltage level shifters that works both ways (If I recalled right I did tested to make sure if the lower voltage side can bring the ps2 lines low).

PS you should not use a voltage divider to knock the voltage for 3.3v boards, it not possible for the board to send data to the keyboard and ps2 keyboards used a open collector output with a pull up resistor. The voltage divider resistor could pull the lines down too low at the keyboard and make it not work, or add to much noise that makes it hard for the board to read the lines (if you do use a voltage divider, a 10k over 20k works the best for me and is the lowest values that works with all keyboards).

On the SAMD boards everything worked expect the ability to send data to the keyboard. I think the SAMD boards are not supported by the library. I tried doing the things the porting readme file said, but I couldn't get the boards sending data to the keyboard.

I have got around the problem of pressing the lock key and everything breaking by modifying the library to rebind the keys to different useless keys. When ever you press a lock key, the board send data to the keyboard to update the lock led. When you rebind the keys the board will not try to send data. On about half of the keyboards I have tested, if you press num lock the led will come on (or turn off if it was on) even if the keyboard data/clock lines are not connected to anything.

The quick fix that I did was rebind the lock keys to lang keys. To do this open up the file called PS2KeyCode.h and change defines for the locks keys (lines 115-117) to this:
#define PS2_KC_NUM 0XF2 // was 0x77, lang1, switch lang and lock keys bacuse lock keys break everything #define PS2_KC_SCROLL 0XF1 // was 0x7E, lang2 #define PS2_KC_CAPS 0X63 // was 0x58, lang3
After that change defines for the lang keys (lines 226-228) to this:
#define PS2_KC_LANG1 0x77 // was 0XF2, num lock #define PS2_KC_LANG2 0x7E // was 0XF1, scroll lock #define PS2_KC_LANG3 0x58 // was 0X63, cap lock

@techpaul
Copy link
Owner

techpaul commented Jul 2, 2022

I do assume you powered keyboard from 5V pin and added a VIN, all arduino style boards take extrenal 7 -12V power on VIN connector (and pin), which is then passed to a 5V 1A regulator.

Use of USB keyboards with PS2 adapters WILL have power issues.

Voltage dividers are not bidirectional

If issue is related to LED lighting and not to sending other commands, it may well be power and or keyboard issue.

Issues on interrupts are all due to lack of support from EARLIEST Arduino board for an attachinterupt() not having the optional parameter to clear any pending interrupts, internal hardware detection of changes before interrupt is enabled. The change of direction to send data WILL cause a low or falling edge, falsely trigger an extra interrupt calling itself.

If the hardware and software supported clearing pending interrupts it would be simpler.

Many processors have funny ways of handling interrupts and many of them have ports and interrupt logic that i weird so there is no STANDARD implementation across all platforms to clear pending interrupts whilst attaching an new interrupt function to a pin.

Look at code around

  • Lines 418 to 422
  • Line 481 to 485
  • Lines 486 to 518

How each processor handles detach/attachinterrupt with a pin change is hardware and board support package dependant.

SAMD1 - Seeeduino Xiao M0+ and ESP32 - ESP32 (arduino-esp32) are user supplied fixes, that may well have ONLY worked for their specific board, not the families.

@giobbino
Copy link

Hello, I have the same problem, but I wish to add some more details (at least in my case):

  1. I'm using a PS2 Keyboard (tested with two different keyboards);

  2. the problem is with the three keys that drive the keyboard LEDs: caps lock, num lock and scroll lock;

  3. the code works fine with Arduino Uno, but doesn't work with LGT8F328 Nano boards - Variant: LQFP32 (that should be a drop-in replacement for the Arduino Nano). Unfortunately I haven't a genuine Arduino Nano to test...

  4. the problem should not be a current issue: I powered the keyboard with my digital power supply (instead to use the +5v from the Arduino-clone board) but it hangs the same way;

  5. it hangs the keyboard (or the keyboard.available() function), not the whole board; I add a couple of lines to make the internal led to blink when no keys are pressed, and it continues to blink.

  6. sometimes after to hit the Caps Lock it still can read one more keystroke, but returns a wrong value and then hangs

@techpaul
Copy link
Owner

Hello, I have the same problem, but I wish to add some more details (at least in my case):

1. I'm using a PS2 Keyboard (tested with two different keyboards);

Good data point

2. the problem is with the three keys that drive the keyboard LEDs: caps lock, num lock and scroll lock;

So when changing direction of data and clock line or back again, something gets out of sync, this is nomally interrupt related (hardware, board support package or other issue) often biggest problem is clearing pending interrupt status, that is board dependant. This is when the previous change on an pin has been registered but not created an interrupt, most board packages do not have the ability to clear this status when doing attachinterrupt. so creates a bogus interrupt.

This varies between board and board families

Often this involves reading data sheets for the processor and the core libraries for that processor to understand what is happening.

3. the code works fine with Arduino Uno, but doesn't work with LGT8F328 Nano boards - Variant: LQFP32 (that _should_ be a drop-in replacement for the Arduino Nano). Unfortunately I haven't a genuine Arduino Nano to test...

I do not have a Nano (genuine or clone) currently not listed as known working board, but as stated previoiusly jugging what extras are included or not by manipulating the supported mothods in PS2KeyAdvanced.h around line 148 onwards. Preferably by creating a specic arcitecture comparison targeted for Nano.

This can be done by conitional assembly withing the ARDUINO_ARCH_AVR checks to also check for ARDUINO_AVR_NANO

4. the problem should not be a current issue: I powered the keyboard with my digital power supply (instead to use the +5v from the Arduino-clone board) but it hangs the same way;

Many problems have transpired in the past to be on supported boards but using typically a USB keyboard that is power hungry. This may not be the case here.

5. it hangs the keyboard (or the keyboard.available() function), not the whole board; I add a couple of lines to make the internal led to blink when no keys are pressed, and it continues to blink.

I suspect nothing is hanging as such (unless you are looping only on keyboard.available in your project), it sounds to me like there is an issue with interrupt handling and/or redefining ports that is causing things to get out of sync, as other parts of your project are working. By being out of sync it never gets back into sync to correctly decode serial bitstream.

Do you see any valid return codes for sending the data to turn LED on or off ?

6. sometimes after to hit the Caps Lock it still can read one more keystroke, but returns a wrong value and then hangs

Still suggests there is an interrupt issue or dodgy connection causing fake interrupts.

Are you able to examine the wires using a scope?

As I have said before --

If the hardware and software supported clearing pending interrupts it would be simpler.

Many processors have funny ways of handling interrupts and many of them have ports and interrupt logic that i weird so there is no STANDARD implementation across all platforms to clear pending interrupts whilst attaching an new interrupt function to a pin.

Look at code around

Lines 418 to 422
Line 481 to 485
Lines 486 to 518

How each processor handles detach/attachinterrupt with a pin change is hardware and board support package dependant.

@giobbino
Copy link

I will try to make a test with an Arduino Nano. For now I temporarily solved with the @sam-was-here patch.

Lines 418 to 422 Line 481 to 485 Lines 486 to 518

I'm not sure if you suggested to define PS2_CLEAR_PENDING_IRQ or not...

Are you able to examine the wires using a scope?
`

I could do that (I have an USB scope) but I don't know what to look at, so probably the answer should be "no"...

@techpaul
Copy link
Owner

Been busy with family issues for a while.

As I do not have any Nano's or the full datasheets etc

Try both CLEAR_PENDING_IRQ and NOT and see the reults.

As to scoping the details are in the extras folder of the library

PS"Keyboard.pdf document describing the wires and sequences.

images folder has scope shots of what it looks like for a few keypresses.

@MattisLind
Copy link

I have the same type of problem.

I.e. After certain commands that require an argument it locks up. For example get scan code set or setting locks ( pressing numlock causes it to lock up in the advcodetest program ) After a reset of the STM32 board it works fine. It appears that it is waiting for a condition that never happens.

I have an original IBM PS/2 keyboard dated 1988. It consumes around 130 mA. I have been using the advcodetest in the examples folder.

I am using a STM32 Blue Pill. With the https://github.com/rogerclarkmelbourne/Arduino_STM32 framework.

I have been adding code to trace what is going on but not yet got a full conclusion. But it appears that the keyboard is not happy with the argument byte and sends a FE in response. However the FE is not properly received by the code in the STM32. It looks like the stop bit is never received. Or actually as the start bit is lost and that bit 0 of FE is detected as the start bit. Thus one clk transition is missing to complete reception of the byte.

I have tried to compile the code with the PS2_CLEAR_PENDING_IRQ defined and undefined. I could not see any difference from this.

Next I will do is to attach the logic analyzer or scope to do a capture of what is happening on the wire.

@MattisLind
Copy link

MattisLind commented Oct 29, 2022

So I cobbled together some quick code on an STM32 Blue pill with the Arduino_STM32 framework linked above. The code has taken a few lines from your code but the state machine is new.

It can send various commands to the keyboard for setting/resetting LEDs and setting different scan sets. All works as intended. I haven't figured out why your library isn't working, but it is possible to get it to work on the hardware I have so it is not a hardware issue.

 Test code to set a PS/2 keyboard into Code set 3
*/

char txByte;
char txMode=0;
int cnt=0;
char busy;
char rxByte;
char parity=1; 
char rxDone;
char txState;
void ISR () {
  char bit;
  if (txMode) {
    Serial.print(cnt,DEC);
    if (cnt >=0 && cnt <8) {
      Serial.print("D");
      bit = txByte & 0b00000001;
      txByte >>= 1;
      parity ^= bit;
      cnt++;
      digitalWrite(PB3, bit);
      Serial.print(bit, HEX);
    } else if (cnt==8) {
      Serial.print("P");
      digitalWrite(PB3, parity);
      Serial.print(parity, HEX);
      cnt++;
    } else if (cnt == 9) {
      Serial.print(".");
      digitalWrite(PB3, HIGH);
      pinMode(PB3, INPUT_PULLUP);
      cnt++;
    } else if (cnt == 10 ) {
      Serial.print("A");
      Serial.print(digitalRead(PB3));
      txMode = 0;
      Serial.println(); 
      busy = 0;
      cnt = 0;
    }
  } else {
    Serial.print(cnt,DEC);
    bit = digitalRead(PB3);
    Serial.print(bit, HEX);
    Serial.print("-");
    if (cnt >0 && cnt <9) {
      Serial.print("D");
      parity ^= bit;
      cnt++;
      rxByte >>= 1;
      if (bit) rxByte |= 0b10000000;

    } else if (cnt==0) {
      parity=0;
      Serial.print("S");
      rxByte = 0;
      busy = 1;
      cnt++;  
    } else if (cnt==9) {
      parity  ^= 1;
      if (parity == bit) Serial.print("P");
      else Serial.print("X");
      //Serial.print(parity, HEX);
      cnt++;
    } else if (cnt == 10) {
      Serial.print(".");
      cnt = 0;
      busy = 0;
      rxDone = 1;
      if (rxByte < 16) Serial.print("0");
      Serial.print(rxByte, HEX);
      Serial.println();
    }
  }
}

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PB3, INPUT_PULLUP);
  pinMode(PB5, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PB5),ISR,FALLING); 
  Serial.begin(9600);
  Serial.print("PS2COMMANDER> ");
}


void startTx (char byteToSend) {
  busy = 1;
  parity = 1;
  txByte = byteToSend;
  // Setting pin output low will cause interrupt before ready
  detachInterrupt( digitalPinToInterrupt( PB5 ) );
  // set pins to outputs and high
  digitalWrite( PB3, HIGH );
  pinMode( PB3, OUTPUT );
  digitalWrite( PB5, HIGH );
  pinMode( PB5, OUTPUT );
  // Essential for PS2 spec compliance
  delayMicroseconds( 10 );
  // set Clock LOW
  digitalWrite( PB5, LOW );
  // Essential for PS2 spec compliance
  // set clock low for 60us
  delayMicroseconds( 60 );
  // Set data low - Start bit
  digitalWrite( PB3, LOW );
  delayMicroseconds( 1 );
  // set clock to input_pullup data stays output while writing to keyboard
  pinMode( PB5, INPUT_PULLUP );
  txMode = 1;
  // Restart interrupt handler
  attachInterrupt( digitalPinToInterrupt( PB5 ), ISR, FALLING );
  //  wait clock interrupt to send data
}

char firstByte;
char secondByte;

void processSendFSM () {
  if (txState==1) {
    startTx(firstByte);
    rxDone = 0;
    txState=2;
  } else if (txState == 2) { 
    if (rxDone==1) {
      delayMicroseconds( 50 ); 
      startTx(secondByte);
      txState = 0;
    }
  }  
}

void sendSetScanCodeSet(char scancodeset) {
 txState = 1;
 secondByte = scancodeset;
 firstByte = 0xF0; 
}

void sendSetResetLEDs(char ledState) {
   txState = 1;
   secondByte = ledState;
   firstByte = 0xED;  
}
char leds=0;

// the loop function runs over and over again forever
void loop() {
  char inputChar;
  processSendFSM();
  if (Serial.available()) {
    inputChar = Serial.read();
    Serial.write(inputChar);
    Serial.println();
    switch (inputChar) {
      case 'S':
      case 's':
        Serial.println("Send Code set 2 to keyboard.");
        if (busy) {
          Serial.println("ERROR - receiver busy");
          break;
        }
        
        sendSetScanCodeSet(0x02);
        break;
      case 'T':
      case 't':
       Serial.println("Send Code set 3 to keyboard."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       sendSetScanCodeSet(0x03);
       break;
      case 'U':
      case 'u':
       Serial.println("Send Code set 1 to keyboard."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       sendSetScanCodeSet(0x01);
       break;
      case 'G':
      case 'g':
       Serial.println("Get scan code set."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       sendSetScanCodeSet(0x00);
       break; 
      case 'I':
      case 'i':
       Serial.println("Get ID."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       startTx(0xF2);
       break;  
      case 'E':
      case 'e':
       Serial.println("Send Echo"); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       startTx(0xEE);
       break;   
      case 'R':
      case 'r':
       Serial.println("Send Reset"); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       startTx(0xFF);
       break;    

      case 'L':
      case 'l':
       Serial.println("Toggle Caps Lock."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       leds^= 0b00000100;
       sendSetResetLEDs(leds);
       break;    
      case 'M':
      case 'm':
       Serial.println("Toggle Num Lock."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       leds^= 0b00000010;
       sendSetResetLEDs(leds);
       break;  
      case 'N':
      case 'n':
       Serial.println("Toggle Scroll Lock."); 
       if (busy) {
         Serial.println("ERROR - receiver busy");
          break;
       }
       leds^= 0b00000001;
       sendSetResetLEDs(leds);
       break;                                                 
    }
    Serial.print("PS2COMMANDER> ");
  }

}

@techpaul
Copy link
Owner

techpaul commented Oct 29, 2022

Why do you WANT to set Scan Code Set 3 ????

It is a RARELY available OPTIONAL mode hence anything that happens after that is not supported. Even Num Lock codes change. See the PS2Keyboard.pdf document in the library's extra folder page 9 where it discusses code sets. Many keyboards do NOT actually support scan code set 1 either (the old XT spec)

"Scan Code Set 3 - Optional PS/2 scan code set--rarely used"

0xFE is the RESEND code because what was received was garbled or possibly on some keyboards wrongly sent for invalid command or data..

Note also on bottom of page 10 of the same document that most commands ONLY have effect in Scan Code set 2

"The next six commands can be issued when the keyboard is in any mode, but it only effects the behavior of
the keyboard when in "mode 3" (ie, set to scan code set 3.)"

If you manage to set scan code set 3 all bets are off. If you NEED scan set 3 you need to look at the differeneces and note that those that MIGHT support set 3 some broken installations in the keyboards.

See table (9.6 Table) and notes (section 9.5 Use) for example on this site

https://web.stanford.edu/class/cs140/projects/pintos/specs/kbd/scancodes-9.html#ss9.1

@MattisLind
Copy link

MattisLind commented Oct 29, 2022

I need scan code set 3 because that is what my system expects. Easy. And yes it is available on my original IBM PS/2 keyboard. Works as expected.

But that is not the point. The point is that when testing your library it hangs. It isn’t even possible to retrieve the current scan code setting neither set the leds. When using my simple test code it doesn’t hang and leds are set as expected. It has NOTHING to do with scan code sets.

Don’t mix up things.

@techpaul
Copy link
Owner

techpaul commented Oct 31, 2022

First the Framework you are using has NOT BEEN TESTED or USER SUPPLIED fixes., NO I am not going to test that framework there are too many board support packages, you are welcome to supply actual fixes for Scan Code Set 2 for that experimental framework.. See following for known working board support packages

https://github.com/techpaul/PS2KeyAdvanced/blob/master/README.md

Second the CPU or Framework may well not handle the interrupts in a different manner, there are some like ESP32 that has actual hardware issues for interrupts see Issue #21 I have NO idea of interrupt issues about pending, edges or not, potentially missing interrupts of framework issues with interrupts.

Thirdly you have not provided details like what keycode sequence from power up causes the error, so any sequence issue cannot be traced.

Fourthly using Scan Code Set 3 WILL cause issues as key mapping changes e.g. Num Lock changes from 77 to 76. Which on Scan Code Set 2 is ESC. Turns out 77 is actually Keypad diviide key, so what happens when you use that key instead of Num lock? Any key that requires a 2 or 8 byte sequence is then incorrectly mapped, break codes will cause issues due to different mapping. The library may well be receiving codes that makes it think either it is

  • Receiving a sequenece expecting more bytes then not receiving a valid sequence.
  • Receiving INVALID codes so NOT returning any value

So without MUCH more detail and Scan Code Set 2 usage I cannot give any ideas.

@MattisLind
Copy link

OK. I understand.

I have provided information on what kind of test setup I tried in my first message if you cared to read it through. I used your example program advcodetest and tested the sequence for getting scan code set and also pressing the caps lock key.

Both of them hang the library.

This has NOTHING to do with scan code set 3.

So I posted a simple message that with (non-experimental) framework based on the much used Maple framework it wasn't working, much like the reports from people which had been using ESP32 or some Atmega328-based boards.

I spent quite some time trying to figure out the workings of your library but didn't get to more detail than it seemed that the keyboard wasn't happy with the argument byte for some reason. The actual command byte was fine and it responded with a 0xFA for this byte (All one byte command worked fine, those with arguments didn't).

So I thought that since the protocol is well described I pull together some code that send two byte command to see if I get into the same problem with my code. I didn't. It was not any problem to send two byte commands and get the proper responses.

Since part of project is to get the keyboard into scan code set 3 I wrote that in the comment of my code which apparently made you bark up the wrong tree. I never asked anything about scan code set 3 in my message. It was just the comment of the code.

I just tried to be friendly and provide an example of working code on a specific platform that wasn't working with your library. This would rule out platform deficiencies and power supply issues. If it works with my code, it should be possible to get your library working as well. If you want.

Since a number of reports has came with different platforms having exactly the same problem I would think there is a timing problem in your library.

No. I am not going to fix you library. I am going to use my own code. I am not expecting you do to anything at all. It was just a friendly note that perhaps there is an issue with your library since several people had noted it and by providing code you might possibly find out what the problem is.

BTW. I never expected your library to work with Scan code set 3. It was quite obvious when I locked into the code. I would have ripped out the key mapping from the library anyway If I were to use it. Now I am not.

I feel certain hostility from your side when you get feedback. Feedback is a good thing. Now I tried to provide constructive feedback on how to improve the library.

I will end here. Good luck with your library.

@techpaul
Copy link
Owner

OK. I understand.

I have provided information on what kind of test setup I tried in my first message if you cared to read it through. I used your example program advcodetest and tested the sequence for getting scan code set and also pressing the caps lock key.

But no idea of any other actions that may or may not have happened even just standard keys Both of these functions require chanmge of direction for data line and overriding clock line, this in turn requires fiddling with interrupts.

Both of them hang the library.

They hang the who;le application, as the library for bit reception is interrupt controlled.

This has NOTHING to do with scan code set 3.

I have had ONE other case of someone wanting Code Set 3 but their keyboard did NOT support it anyway.

So I posted a simple message that with (non-experimental) framework based on the much used Maple framework it wasn't working, much like the reports from people which had been using ESP32 or some Atmega328-based boards.

There are many reasons often lack of power to keyboard as some keyboards can take up to 200mA which is MORE than their boards can supply and causes power dips RESETING the keyboard.

In case of ESP32 there is actual CPU hardware issues of missing interrupts.

Others have other causes which needs detailed knowledge of interrupts on the CPU and the framework, as all frameworks can give spurious extra interrupts as the original Arduino frameowrk doies not support any clear pending interrupts for changes on a pin BEFORE it becomes an interrupt pin, so one or more spurious interrupts can occur.

I spent quite some time trying to figure out the workings of your library but didn't get to more detail than it seemed that the keyboard wasn't happy with the argument byte for some reason. The actual command byte was fine and it responded with a 0xFA for this byte (All one byte command worked fine, those with arguments didn't).

This is different to your initial report of

Or actually as the start bit is lost and that bit 0 of FE is detected as the start bit. Thus one clk transition is missing to complete reception of the byte.

0xFE is a RESEND byte for garbled data received (usually a parity error) whilst 0xFA is am ACK which is different) Here knowing what was happening on the wires would be useful.

Clock transmissions missing is often due to how CPU and framework handle interrupts (long before the library callback function), whether this is extra interrupts due to not clearing pending interrupts not supporting edge transitions so two interrupts occuir for every keyboard clock cycle, or MISSING interrupts or other reasons before the library, I cannot tell.

Please bear in mind even though a program may request interrupt type oif FALLING edge some do not support this but change it to LOW or CHANGE, causing extra issues. Hence defines for PS"_CLEAR_PENDING_IRQ and PS2ONLY_CHANGE_IRQ

So I thought that since the protocol is well described I pull together some code that send two byte command to see if I get into the same problem with my code. I didn't. It was not any problem to send two byte commands and get the proper responses.

The issue is not number of bytes, it is to do mainly with interrupt handling, disablig/reanbling and types available

I just tried to be friendly and provide an example of working code on a specific platform that wasn't working with your library. This would rule out platform deficiencies and power supply issues. If it works with my code, it should be possible to get your library working as well. If you want.

That is a lot of code to decipher actions on what is potentially just how the CPU and framework handles and configures interrupts for that board. Working out what is the same and different takes a lot of time, taking scopeshots of good and bad is more helpful to prove what happens on the wires first.

Since a number of reports has came with different platforms having exactly the same problem I would think there is a timing problem in your library.

No many different problems, most were power related to using a USB keyboard through a PS2 adapter and browning out the power to keyboard, quite a few were solved by externally powering their board and not using the same USB power for their platform and keyboard.

As the code works on 12MHz AVR and 84MHz ARM, I do not think it is timing it is around changing direction fo dataflow and interrupts related to a framework and CPU. Most STM32s I have seen run at 32MHz tops, and I have been working with some on products that sell in their 1000's, but never with Arduino style frameworks.

No. I am not going to fix you library. I am going to use my own code. I am not expecting you do to anything at all. It was just a friendly note that perhaps there is an issue with your library since several people had noted it and by providing code you might possibly find out what the problem is.

That is your choice, but code alone does not help without knowing more of the framework implementation mainly of interrupts

I feel certain hostility from your side when you get feedback. Feedback is a good thing. Now I tried to provide constructive feedback on how to improve the library.

Exasparation and frustration from numbers using untested platforms and expect me to purchase their platform and solve the issue.

I will end here. Good luck with your library.

@cmcooper1971
Copy link

SAMD1 - Seeeduino Xiao M0+ and ESP32 - ESP32 (arduino-esp32) are user supplied fixes, that may well have ONLY worked for their specific board, not the families.

Hi TechPaul,

Thanks for your library, I have been having a lot of fun with it.

Concerning this sentence above, I don't suppose you know who has got this working on an ESP32 do you?

I have it all working on an Uno, but I have linked my Uno to an ESP32 for the Bluetooth via Serial, as I would like to use it as a Bluetooth HID.

It works except when I use the lock keys. I have proven this by disabling the Serial link between the Uno an ESP and everything works. My plan is to move all of my code to the ESP and turn the keyboard into a wireless HID device.

I need to know from someone, can I use any GPIO or have they fixed it to certain ones? Also, reading this thread, did they have do anything with the code?

For info, my keyboard is a Cherry MX 3000M / G80-3000HFMGB /03

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants