-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsaturn.ino
133 lines (119 loc) · 3.34 KB
/
saturn.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// TimerOne & TimerThree Libraries
// https://www.pjrc.com/teensy/td_libs_TimerOne.html
#include <TimerOne.h>
// Arduino Joystick Library
// https://github.com/MHeironimus/ArduinoJoystickLibrary
#include <Joystick.h>
// Arduino Pro Micro (32U4) - This part can not change.
// PORTB D11 D10 D9 D8 MISO MOSI SCLK TX_LED
#define S0 8
#define S1 9
// PIND D6 D12 RX D4 D1 D0 D2 D3
#define Y0 2
#define Y1 3
#define Y2 4
#define Y3 6
// 512 Hz - 128 Hz per controller
#define SCAN_FREQ 976
#define JOYSTICK_BUTTON_COUNT 9
#define JOYSTICK_CONNECTION 1
Joystick_ Joystick(
JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_GAMEPAD,
JOYSTICK_BUTTON_COUNT,
JOYSTICK_CONNECTION,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
);
uint8_t page[4] = { B00000000, B00010000, B00100000, B00110000 };
uint8_t lastButtonState[3][4] = {
{ 1, 1, 0, 0 }, // L - - -
{ 1, 1, 1, 1 }, // R X Y Z
{ 1, 1, 1, 1 } // S A C B
};
uint8_t buttonMap[3][4] = {
{ 4, 9, 9, 9 }, // L - - -
{ 6, 0, 3, 5 }, // R X Y Z
{ 8, 1, 7, 2 } // S A C B
};
uint8_t lastHatState = B00001111;
int16_t roundTable[16];
void scanKeys(void)
{
// read current state
uint8_t currentButtonState[3][4];
uint8_t currentHatState;
for(int i = 0; i < 4; i++) {
// set read page
PORTB = page[i];
// read current level
uint8_t current = PIND;
if(i < 3) {
// buttons
currentButtonState[i][0] = (current >> 7) & B00000001; // D3
currentButtonState[i][1] = (current >> 4) & B00000001; // D2
currentButtonState[i][2] = (current >> 0) & B00000001; // D1
currentButtonState[i][3] = (current >> 1) & B00000001; // D0
} else {
// hat switch
currentHatState =
((current & B00000010) << 2) | // D0 Up
((current & B10000000) >> 5) | // D3 Rt
((current & B00000001) << 1) | // D1 Dn
((current & B00010000) >> 4); // D2 Lt
}
}
// convert joystick button
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 4; j++) {
if(lastButtonState[i][j] != currentButtonState[i][j]) {
Joystick.setButton(buttonMap[i][j], currentButtonState[i][j] ^ B00000001);
lastButtonState[i][j] = currentButtonState[i][j];
}
}
}
// convert joystick hat switch
if(lastHatState != currentHatState) {
Joystick.setHatSwitch(0, roundTable[currentHatState]);
lastHatState = currentHatState;
}
}
void setup()
{
// hat keytable init
roundTable[B00001111] = -1;
roundTable[B00000111] = 0;
roundTable[B00000011] = 45;
roundTable[B00001011] = 90;
roundTable[B00001001] = 135;
roundTable[B00001101] = 180;
roundTable[B00001100] = 225;
roundTable[B00001110] = 270;
roundTable[B00000110] = 315;
// init page pins
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
digitalWrite(S0, LOW);
digitalWrite(S1, LOW);
// init data pins
pinMode(Y0, INPUT_PULLUP);
pinMode(Y1, INPUT_PULLUP);
pinMode(Y2, INPUT_PULLUP);
pinMode(Y3, INPUT_PULLUP);
Joystick.begin();
Timer1.initialize(SCAN_FREQ);
Timer1.attachInterrupt(scanKeys);
}
void loop()
{
delay(100);
}