Last active
August 23, 2021 10:20
-
-
Save imax9000/26eab1c9bec56f2afbe918df5f6a548d to your computer and use it in GitHub Desktop.
DMG button pusher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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