Skip to content

Commit

Permalink
Disable PS2 pullup when power supply is off
Browse files Browse the repository at this point in the history
This is to prevent trying to power the keyboard via the PS2 ports when the
power supply is off.
  • Loading branch information
stople committed May 26, 2024
1 parent c948ad7 commit c8ca540
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
13 changes: 11 additions & 2 deletions ps2.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "optimized_gpio.h"
#define SCANCODE_TIMEOUT_MS 50

bool PWR_ON_active();

enum PS2_CMD_STATUS : uint8_t {
IDLE = 0,
CMD_PENDING = 1,
Expand Down Expand Up @@ -44,8 +46,15 @@ class PS2Port
};

virtual void resetInput() {
gpio_inputWithPullup(datPin);
gpio_inputWithPullup(clkPin);
if (PWR_ON_active()) {
gpio_inputWithPullup(datPin);
gpio_inputWithPullup(clkPin);
} else {
// Prevent powering the keyboard via the pull-ups when system is off
// Call reset() after changing PWR_ON
pinMode_opt(datPin, INPUT);
pinMode_opt(clkPin, INPUT);
}
curCode = 0;
parity = 0;
rxBitCount = 0;
Expand Down
21 changes: 18 additions & 3 deletions x16-smc.ino
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ void setup() {

// Setup Power Supply
pinMode_opt(PWR_OK, INPUT);
pinMode_opt(PWR_ON, OUTPUT);
digitalWrite_opt(PWR_ON, HIGH);
pinMode_opt(PWR_ON, OUTPUT);

// Turn Off Activity LED
pinMode_opt(ACT_LED, OUTPUT);
Expand Down Expand Up @@ -317,6 +317,8 @@ void PowerOffSeq() {
digitalWrite_opt(ACT_LED, ACT_LED_OFF); // Ensure activity LED is off
_delay_ms(AUDIOPOP_HOLDTIME_MS); // Wait for audio system to stabilize before power is turned off
digitalWrite_opt(PWR_ON, HIGH); // Turn off supply
Keyboard.reset(); // Reset and deactivate pullup
Mouse.reset(); // Reset and deactivate pullup
SYSTEM_POWERED = 0; // Global Power state Off
_delay_ms(RESB_HOLDTIME_MS); // Mostly here to add some delay between presses
deassertReset();
Expand All @@ -325,6 +327,8 @@ void PowerOffSeq() {
void PowerOnSeq() {
assertReset();
digitalWrite_opt(PWR_ON, LOW); // turn on power supply
Keyboard.reset(); // Reset and activate pullup
Mouse.reset(); // Reset and activate pullup
unsigned long TimeDelta = 0;
unsigned long StartTime = millis(); // get current time
while (!digitalRead_opt(PWR_OK)) { // Time how long it takes
Expand All @@ -336,8 +340,6 @@ void PowerOnSeq() {
// insert error handler, flash activity light & Halt? IE, require hard power off before continue?
}
else {
Keyboard.flush();
Mouse.reset();
defaultRequest = I2C_CMD_GET_KEYCODE_FAST;
_delay_ms(RESB_HOLDTIME_MS); // Allow system to stabilize
SYSTEM_POWERED = 1; // Global Power state On
Expand Down Expand Up @@ -594,3 +596,16 @@ ISR(TIMER1_COMPA_vect) {
Keyboard.timerInterrupt();
Mouse.timerInterrupt();
}

bool PWR_ON_active()
{
// Returns the status of the PWR_ON output port.
// PWR_ON is active low.
// Thus, return true if DDR is output (1) and if PORT is low (0).
// Similar to the SYSTEM_POWERED variable, but this is more accurate when power is changing.
// A future code improvement can be to make gpio functions to read from PORT/DDR register
// PWR_ON is 5, which is PA5

if ((DDRA & _BV(5)) == 0) return false; // Port is input. This is the case when mouse and keyboard objects are created
return (PORTA & _BV(5)) ? false : true;
}

0 comments on commit c8ca540

Please sign in to comment.