Skip to content

Commit 46b1e08

Browse files
committed
nunchuck and gamecube fixes
1 parent 45d8534 commit 46b1e08

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

src/GameControllers.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@
2121

2222
typedef struct {
2323
gpio_dev* device;
24-
volatile uint32_t* port;
2524
uint32_t mask;
2625
uint32_t pinNumber;
2726
} PortData;
2827

2928
typedef struct {
30-
uint8_t buttons;
29+
uint16_t buttons;
3130
uint8_t joystickX;
3231
uint8_t joystickY;
3332
uint8_t cX;
@@ -38,7 +37,7 @@ typedef struct {
3837

3938
typedef struct {
4039
uint8_t device;
41-
uint8_t buttons;
40+
uint16_t buttons;
4241
uint16_t joystickX; // 10 bit range for analog values
4342
uint16_t joystickY;
4443
uint16_t cX;
@@ -51,12 +50,10 @@ class GameController {
5150
protected:
5251
void setPortData(PortData *p, unsigned pin) {
5352
if (pin == INPUT_NOT_IMPLEMENTED) {
54-
p->port = NULL;
5553
p->device = NULL;
5654
}
5755
else {
5856
p->device = digitalPinToPort(pin);
59-
p->port = portOutputRegister(p->device);
6057
p->mask = digitalPinToBitMask(pin);
6158
p->pinNumber = PIN_MAP[pin].gpio_bit;
6259
}
@@ -72,15 +69,18 @@ class GameController {
7269

7370
class NunchuckController : public GameController {
7471
private:
75-
#ifdef NUNCHUCK_SOFT_I2C
76-
TwoWire* wire;
77-
#else
78-
HardWire wire;
79-
#endif
8072
static uint16_t rescale(uint8_t value); // 8 to 10 bit
8173
uint8_t sendBytes(uint8_t location, uint8_t value);
8274
const uint8_t i2cAddress = 0x52;
8375
uint8_t buffer[6];
76+
unsigned scl;
77+
unsigned sda;
78+
#ifdef NUNCHUCK_SOFT_I2C
79+
TwoWire* wire;
80+
#else
81+
HardWire* wire;
82+
#endif
83+
8484

8585
public:
8686
bool begin(void);

src/gamecube.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ static const uint32_t bitReceiveCycles = cyclesPerUS * 4;
88
static const uint32_t halfBitReceiveCycles = cyclesPerUS * 2;
99

1010
GameCubeController::GameCubeController(unsigned p) {
11-
setPortData(&port, p );
11+
setPortData(&port, p);
1212
}
1313

1414
bool GameCubeController::begin() {
@@ -25,13 +25,13 @@ void GameCubeController::sendBits(uint32_t data, uint8_t bits) {
2525
DWT->CYCCNT = 0;
2626
uint32_t timerEnd = DWT->CYCCNT;
2727
do {
28-
*port.port &= ~port.mask;
28+
gpio_write_bit(port.device, port.pinNumber, 0);
2929
if (0x80000000ul & data)
3030
timerEnd += quarterBitSendingCycles;
3131
else
3232
timerEnd += 3 * quarterBitSendingCycles;
3333
while (DWT->CYCCNT < timerEnd) ;
34-
*port.port |= port.mask;
34+
gpio_write_bit(port.device, port.pinNumber, 1);
3535
if (0x80000000ul & data)
3636
timerEnd += 3 * quarterBitSendingCycles;
3737
else
@@ -52,10 +52,12 @@ bool GameCubeController::receiveBits(void* data0, uint32_t bits) {
5252

5353
*data = 0;
5454
do {
55-
if (!(*port.port & port.mask)) {
55+
if (!gpio_read_bit(port.device, port.pinNumber)) {
56+
5657
DWT->CYCCNT = 0;
5758
while (DWT->CYCCNT < halfBitReceiveCycles - 2) ;
58-
if (*port.port & port.mask) {
59+
if (gpio_read_bit(port.device, port.pinNumber)) {
60+
5961
*data |= bitmap;
6062
}
6163
bitmap >>= 1;
@@ -66,7 +68,7 @@ bool GameCubeController::receiveBits(void* data0, uint32_t bits) {
6668
if (bits)
6769
*data = 0;
6870
}
69-
while (0 == (*port.port & port.mask) && --timeout) ;
71+
while (!gpio_read_bit(port.device, port.pinNumber) && --timeout) ;
7072
if (timeout == 0) {
7173
break;
7274
}
@@ -83,12 +85,12 @@ bool GameCubeController::readWithRumble(GameControllerData_t* data, bool rumble)
8385
nvic_globalirq_enable();
8486
delayMicroseconds(400);
8587
fails = 0;
86-
}
88+
}
8789
nvic_globalirq_disable();
8890
sendBits(rumble ? 0b0100000000000011000000011l : 0b0100000000000011000000001l, 25);
8991
bool success = receiveBits(&gcData, 64);
9092
nvic_globalirq_enable();
91-
if (success && 0 == (data->buttons & 0x80) && (data->buttons & 0x8000) ) {
93+
if (success && 0 == (gcData.buttons & 0x80) && (gcData.buttons & 0x8000) ) {
9294
data->device = CONTROLLER_GAMECUBE;
9395
data->buttons = gcData.buttons;
9496
data->joystickX = rescale(gcData.joystickX);

src/nunchuck.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
#include "GameControllers.h"
22
#include <string.h>
33

4-
#define SOFT_I2C // currently, HardWire doesn't work well for hotplugging
4+
#define NUNCHUCK_SOFT_I2C // currently, HardWire doesn't work well for hotplugging
55
// Also, it probably won't well with SPI remap
66

7-
NunchuckController::NunchuckController(unsigned scl, unsigned sda) {
8-
#ifdef NUNCHUCK_SOFT_I2C
9-
wire = new TwoWire(scl, sda, SOFT_STANDARD);
10-
#else
11-
wire = new HardWire(1, 0); // I2C_FAST_MODE);
12-
#endif
7+
NunchuckController::NunchuckController(unsigned _scl, unsigned _sda) {
8+
scl = _scl;
9+
sda = _sda;
1310
}
1411

1512
bool NunchuckController::begin() {
13+
if (wire == NULL) {
14+
#ifdef NUNCHUCK_SOFT_I2C
15+
wire = new TwoWire(scl, sda, SOFT_STANDARD);
16+
#else
17+
#error Hardware I2C has trouble with hotplugging.
18+
wire = new HardWire(1, 0); // I2C_FAST_MODE);
19+
#endif
20+
wire->begin();
21+
}
22+
1623
#ifdef MANUAL_DECRYPT
1724
if (!sendBytes(0x40,0x00)) {
1825
return false;

0 commit comments

Comments
 (0)