Skip to content

Instantly share code, notes, and snippets.

@imax9000
Last active August 23, 2021 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imax9000/26eab1c9bec56f2afbe918df5f6a548d to your computer and use it in GitHub Desktop.
Save imax9000/26eab1c9bec56f2afbe918df5f6a548d to your computer and use it in GitHub Desktop.
DMG button pusher
#include <Arduino.h>
#define BS_B _BV(0)
#define BS_START _BV(1)
#define BS_SELECT _BV(2)
#define BS_A _BV(3)
#define BS_LEFT _BV(0)
#define BS_DOWN _BV(1)
#define BS_UP _BV(2)
#define BS_RIGHT _BV(3)
namespace pin {
const int up = 4;
const int down = 3;
const int left = 2;
const int right = 5;
const int A = 9;
const int B = 8;
const int select = 6;
const int start = 7;
const int left_b = 17;
const int down_start = 16;
const int up_select = 15;
const int right_a = 14;
const int ab_scan = 21;
const int dpad_scan = 20;
}; // namespace pin
volatile uint8_t buttons_state = 0xF;
volatile uint8_t dpad_state = 0xF;
inline void setPortD(uint8_t pins) {
PORTD.OUT = pins;
// PORTD.OUT = (PORTD.OUT & (~0xF)) | (pins & 0xF);
// PORTD.OUTSET = pins & 0xF;
// PORTD.OUTCLR = (~pins) & 0xF;
}
void updateButtonState(int pin, uint8_t button, volatile uint8_t *state) {
if (digitalRead(pin)) {
*state |= button;
Serial.print("Button ");
Serial.print(pin);
Serial.println(" released");
} else {
*state &= ~button;
Serial.print("Button ");
Serial.print(pin);
Serial.println(" pressed");
}
}
void setup() {
Serial.begin(9600);
pinMode(pin::left_b, OUTPUT);
pinMode(pin::down_start, OUTPUT);
pinMode(pin::up_select, OUTPUT);
pinMode(pin::right_a, OUTPUT);
pinMode(pin::ab_scan, INPUT_PULLUP);
pinMode(pin::dpad_scan, INPUT_PULLUP);
digitalWrite(pin::left_b, HIGH);
digitalWrite(pin::down_start, HIGH);
digitalWrite(pin::up_select, HIGH);
digitalWrite(pin::right_a, HIGH);
attachInterrupt(
digitalPinToInterrupt(pin::ab_scan), []() { setPortD(buttons_state); },
FALLING);
attachInterrupt(
digitalPinToInterrupt(pin::dpad_scan), []() { setPortD(dpad_state); },
FALLING);
// Input button pins
for (int pin = 2; pin <= 9; pin++) {
pinMode(pin, INPUT_PULLUP);
}
attachInterrupt(
pin::A, []() { updateButtonState(pin::A, BS_A, &buttons_state); },
CHANGE);
attachInterrupt(
pin::B, []() { updateButtonState(pin::B, BS_B, &buttons_state); },
CHANGE);
attachInterrupt(
pin::select,
[]() { updateButtonState(pin::select, BS_SELECT, &buttons_state); },
CHANGE);
attachInterrupt(
pin::start,
[]() { updateButtonState(pin::start, BS_START, &buttons_state); },
CHANGE);
attachInterrupt(
pin::up, []() { updateButtonState(pin::up, BS_UP, &dpad_state); },
CHANGE);
attachInterrupt(
pin::down, []() { updateButtonState(pin::down, BS_DOWN, &dpad_state); },
CHANGE);
attachInterrupt(
pin::left, []() { updateButtonState(pin::left, BS_LEFT, &dpad_state); },
CHANGE);
attachInterrupt(
pin::right,
[]() { updateButtonState(pin::right, BS_RIGHT, &dpad_state); }, CHANGE);
}
void loop() {}
BOARD := arduino:megaavr:nona4809:mode=off
PORT ?= $(wildcard /dev/cu.usbmodem*)
.PHONY: all upload build format
all: build
format:
clang-format -i $$(find . -name \*.cpp -o -name \*.ino -o -name \*.h)
build: format
arduino-cli compile --fqbn $(BOARD) .
upload: format
arduino-cli compile --fqbn $(BOARD) --upload --port $(PORT) .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment