Trying to fix LinkCable random crash

This commit is contained in:
Rodrigo Alfonso
2023-02-07 17:55:49 -03:00
parent cabc079e3c
commit 607eec3c1f
3 changed files with 50 additions and 44 deletions

View File

@@ -78,8 +78,8 @@ void printTutorial() {
DEBULOG("START: turn on connection");
DEBULOG("(on connection, p1 sends 999)");
DEBULOG("");
DEBULOG("A: send counter++ (once)");
DEBULOG("B: send counter++ (cont)");
DEBULOG("B: send counter++ (once)");
DEBULOG("A: send counter++ (cont)");
DEBULOG("L: send counter++ twice (once)");
DEBULOG("R: send counter++ twice (cont)");
DEBULOG("SELECT: force lag (9k lines)");

View File

@@ -60,6 +60,7 @@
#define LINK_CABLE_BIT_GENERAL_PURPOSE_HIGH 15
#define LINK_CABLE_SET_HIGH(REG, BIT) REG |= 1 << BIT
#define LINK_CABLE_SET_LOW(REG, BIT) REG &= ~(1 << BIT)
#define LINK_CABLE_BARRIER asm volatile("" ::: "memory")
static volatile char LINK_CABLE_VERSION[] = "LinkCable/v4.3.0";
@@ -77,8 +78,6 @@ class LinkCable {
std::queue<u16> incomingMessages[LINK_CABLE_MAX_PLAYERS];
u8 playerCount;
u8 currentPlayerId;
bool isReady = false;
bool isConsumed = false;
};
struct InternalState {
@@ -86,7 +85,6 @@ class LinkCable {
int timeouts[LINK_CABLE_MAX_PLAYERS];
bool IRQFlag;
u32 IRQTimeout;
bool isAddingMessage = false;
};
enum BaudRate {
@@ -119,6 +117,9 @@ class LinkCable {
void deactivate() {
isEnabled = false;
isStateReady = false;
isStateConsumed = false;
isResetting = false;
resetState();
stop();
}
@@ -132,28 +133,43 @@ class LinkCable {
u8 currentPlayerId() { return $state.currentPlayerId; }
bool canRead(u8 playerId) {
if (!$state.isReady)
if (!isStateReady || isStateConsumed)
return false;
LINK_CABLE_BARRIER;
return !$state.incomingMessages[playerId].empty();
}
u16 read(u8 playerId) {
if (!$state.isReady)
if (!isStateReady || isStateConsumed)
return LINK_CABLE_NO_DATA;
LINK_CABLE_BARRIER;
return LINK_CABLE_QUEUE_POP($state.incomingMessages[playerId]);
}
void consume() { $state.isConsumed = true; }
void consume() { isStateConsumed = true; }
void send(u16 data) {
if (data == LINK_CABLE_DISCONNECTED || data == LINK_CABLE_NO_DATA)
return;
_state.isAddingMessage = true;
LINK_CABLE_BARRIER;
isAddingMessage = true;
LINK_CABLE_BARRIER;
push(_state.outgoingMessages, data);
_state.isAddingMessage = false;
LINK_CABLE_BARRIER;
isAddingMessage = false;
LINK_CABLE_BARRIER;
if (isResetting) {
LINK_CABLE_QUEUE_CLEAR(_state.outgoingMessages);
isResetting = false;
}
}
void _onVBlank() {
@@ -238,6 +254,10 @@ class LinkCable {
u32 interval;
u8 sendTimerId;
bool isEnabled = false;
bool isStateReady = false;
bool isStateConsumed = false;
bool isAddingMessage = false;
bool isResetting = false;
bool isReady() { return isBitHigh(LINK_CABLE_BIT_READY); }
bool hasError() { return isBitHigh(LINK_CABLE_BIT_ERROR); }
@@ -246,9 +266,11 @@ class LinkCable {
bool didTimeout() { return _state.IRQTimeout >= timeout; }
void sendPendingData() {
if (_state.isAddingMessage)
if (isAddingMessage)
return;
LINK_CABLE_BARRIER;
transfer(LINK_CABLE_QUEUE_POP(_state.outgoingMessages));
}
@@ -281,9 +303,13 @@ class LinkCable {
LINK_CABLE_QUEUE_CLEAR(state.incomingMessages[i]);
_state.timeouts[i] = LINK_CABLE_REMOTE_TIMEOUT_OFFLINE;
}
LINK_CABLE_QUEUE_CLEAR(_state.outgoingMessages);
_state.IRQFlag = false;
_state.IRQTimeout = 0;
if (isAddingMessage || isResetting)
isResetting = true;
else
LINK_CABLE_QUEUE_CLEAR(_state.outgoingMessages);
}
void stop() {
@@ -313,12 +339,15 @@ class LinkCable {
}
void copyState() {
if ($state.isReady && !$state.isConsumed)
if (isStateReady && !isStateConsumed)
return;
state.isReady = true;
state.isConsumed = false;
LINK_CABLE_BARRIER;
$state = state;
LINK_CABLE_BARRIER;
isStateReady = true;
isStateConsumed = false;
LINK_CABLE_BARRIER;
for (u32 i = 0; i < LINK_CABLE_MAX_PLAYERS; i++)
LINK_CABLE_QUEUE_CLEAR(state.incomingMessages[i]);

View File

@@ -48,7 +48,7 @@
#define LINK_UNIVERSAL_WIRELESS_TX_PER_FRAME 5
#define LINK_UNIVERSAL_MAX_ROOM_NUMBER 32000
#define LINK_UNIVERSAL_INIT_WAIT_FRAMES 10
#define LINK_UNIVERSAL_SWITCH_WAIT_FRAMES 20
#define LINK_UNIVERSAL_SWITCH_WAIT_FRAMES 25
#define LINK_UNIVERSAL_SWITCH_WAIT_FRAMES_RANDOM 10
#define LINK_UNIVERSAL_BROADCAST_SEARCH_WAIT_FRAMES 10
#define LINK_UNIVERSAL_SERVE_WAIT_FRAMES 30
@@ -202,29 +202,9 @@ class LinkUniversal {
u32 getWaitCount() { return waitCount; }
u32 getSubWaitCount() { return subWaitCount; }
void _onVBlank() {
if (!isEnabled)
return;
if (mode == LINK_CABLE)
linkCable->_onVBlank();
}
void _onTimer() {
if (!isEnabled)
return;
if (mode == LINK_CABLE)
linkCable->_onTimer();
}
void _onSerial() {
if (!isEnabled)
return;
if (mode == LINK_CABLE)
linkCable->_onSerial();
}
void _onVBlank() { linkCable->_onVBlank(); }
void _onTimer() { linkCable->_onTimer(); }
void _onSerial() { linkCable->_onSerial(); }
~LinkUniversal() {
delete linkCable;
@@ -247,11 +227,8 @@ class LinkUniversal {
void receiveCableMessages() {
for (u32 i = 0; i < LINK_UNIVERSAL_MAX_PLAYERS; i++) {
// TODO: FIX CRASH
// TODO: RETRIEVE ALL MESSAGES
if (linkCable->canRead(i))
linkCable->read(i);
// push(incomingMessages[i], qran_range(1, 10000));
while (linkCable->canRead(i))
push(incomingMessages[i], linkCable->read(i));
}
}