mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-04-25 08:07:59 -05:00
Implementing clock inversion
This commit is contained in:
parent
3098003634
commit
1a67281d25
|
|
@ -503,7 +503,13 @@ void DebugScene::processCommand(u32 selectedCommandIndex) {
|
|||
log("[room.game] " + gameName);
|
||||
log("[room.user] " + userName);
|
||||
|
||||
return linkRawWireless->broadcast(gameName, userName, (u16)gameId);
|
||||
bool success =
|
||||
linkRawWireless->broadcast(gameName, userName, (u16)gameId);
|
||||
|
||||
if (success)
|
||||
log("NOW CALL 0x19!");
|
||||
|
||||
return success;
|
||||
});
|
||||
}
|
||||
case 0x17: {
|
||||
|
|
@ -599,8 +605,14 @@ void DebugScene::processCommand(u32 selectedCommandIndex) {
|
|||
});
|
||||
}
|
||||
case 0x1e: {
|
||||
return logOperation("sending " + name,
|
||||
[]() { return linkRawWireless->broadcastReadEnd(); });
|
||||
return logOperation("sending " + name, []() {
|
||||
bool success = linkRawWireless->broadcastReadEnd();
|
||||
|
||||
if (success)
|
||||
log("NOW CALL 0x1f!");
|
||||
|
||||
return success;
|
||||
});
|
||||
}
|
||||
case 0x1f: {
|
||||
u16 serverId = selectServerId();
|
||||
|
|
@ -646,12 +658,33 @@ void DebugScene::processCommand(u32 selectedCommandIndex) {
|
|||
return;
|
||||
u32 bytes = data[0];
|
||||
data.erase(data.begin());
|
||||
|
||||
return logOperation("sending " + name, [&data, bytes]() {
|
||||
return linkRawWireless->sendData(data, bytes);
|
||||
});
|
||||
}
|
||||
case 0x25: {
|
||||
// TODO: IMPLEMENT
|
||||
auto data = selectDataToSend();
|
||||
if (data.empty())
|
||||
return;
|
||||
u32 bytes = data[0];
|
||||
data.erase(data.begin());
|
||||
|
||||
return logOperation("sending " + name, [&data, bytes]() {
|
||||
LinkRawWireless::RemoteCommand remoteCommand;
|
||||
bool success =
|
||||
linkRawWireless->sendDataAndWait(data, remoteCommand, bytes);
|
||||
|
||||
if (success) {
|
||||
log("< [notif] " + linkRawWireless->toHex(remoteCommand.commandId));
|
||||
for (u32 i = 0; i < remoteCommand.params.size(); i++) {
|
||||
log("< [param" + std::to_string(i) + "] " +
|
||||
linkRawWireless->toHex(remoteCommand.params[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
});
|
||||
}
|
||||
case 0x26: {
|
||||
return logOperation("sending " + name, []() {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#define LINK_RAW_WIRELESS_COMMAND_IS_FINISHED_CONNECT 0x20
|
||||
#define LINK_RAW_WIRELESS_COMMAND_FINISH_CONNECTION 0x21
|
||||
#define LINK_RAW_WIRELESS_COMMAND_SEND_DATA 0x24
|
||||
#define LINK_RAW_WIRELESS_COMMAND_SEND_DATA_AND_WAIT 0x25
|
||||
#define LINK_RAW_WIRELESS_COMMAND_RECEIVE_DATA 0x26
|
||||
#define LINK_RAW_WIRELESS_COMMAND_BYE 0x3d
|
||||
|
||||
|
|
@ -84,6 +85,12 @@ class LinkRawWireless {
|
|||
std::vector<u32> responses = std::vector<u32>{};
|
||||
};
|
||||
|
||||
struct RemoteCommand {
|
||||
bool success = false;
|
||||
u8 commandId = 0;
|
||||
std::vector<u32> params = std::vector<u32>{};
|
||||
};
|
||||
|
||||
struct Server {
|
||||
u16 id = 0;
|
||||
u16 gameId;
|
||||
|
|
@ -425,6 +432,27 @@ class LinkRawWireless {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool sendDataAndWait(std::vector<u32> data,
|
||||
RemoteCommand& remoteCommand,
|
||||
u32 _bytes = 0) {
|
||||
u32 bytes = _bytes == 0 ? data.size() * 4 : _bytes;
|
||||
u32 header = sessionState.currentPlayerId == 0
|
||||
? bytes
|
||||
: (bytes << (3 + sessionState.currentPlayerId * 5));
|
||||
data.insert(data.begin(), header);
|
||||
log("using header " + toHex(header));
|
||||
|
||||
if (!sendCommand(LINK_RAW_WIRELESS_COMMAND_SEND_DATA_AND_WAIT, data)
|
||||
.success) {
|
||||
reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
remoteCommand = receiveCommandFromAdapter();
|
||||
|
||||
return remoteCommand.success;
|
||||
}
|
||||
|
||||
bool receiveData(ReceiveDataResponse& response) {
|
||||
auto result = sendCommand(LINK_RAW_WIRELESS_COMMAND_RECEIVE_DATA);
|
||||
response.data = result.responses;
|
||||
|
|
@ -504,13 +532,79 @@ class LinkRawWireless {
|
|||
std::to_string(responses) + ":");
|
||||
u32 responseData = transfer(LINK_RAW_WIRELESS_DATA_REQUEST);
|
||||
result.responses.push_back(responseData);
|
||||
log("<< " + std::to_string(responseData));
|
||||
log("<< " + toHex(responseData));
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
RemoteCommand receiveCommandFromAdapter() {
|
||||
RemoteCommand remoteCommand;
|
||||
|
||||
log("setting SPI to SLAVE");
|
||||
linkSPI->activate(LinkSPI::Mode::SLAVE);
|
||||
|
||||
log("WAITING for adapter cmd");
|
||||
u32 command = linkSPI->transfer(LINK_RAW_WIRELESS_DATA_REQUEST);
|
||||
if (!reverseAcknowledge()) {
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
reset();
|
||||
return remoteCommand;
|
||||
}
|
||||
|
||||
u16 header = msB32(command);
|
||||
u16 data = lsB32(command);
|
||||
u8 params = msB16(data);
|
||||
u8 commandId = lsB16(data);
|
||||
if (header != LINK_RAW_WIRELESS_COMMAND_HEADER) {
|
||||
log("! expected HEADER 0x9966");
|
||||
log("! but received 0x" + toHex(header));
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
reset();
|
||||
return remoteCommand;
|
||||
}
|
||||
log("received cmd: " + toHex(commandId) + " (" + std::to_string(params) +
|
||||
" params)");
|
||||
|
||||
for (u32 i = 0; i < params; i++) {
|
||||
log("param " + std::to_string(i + 1) + "/" + std::to_string(params) +
|
||||
":");
|
||||
u32 paramData = linkSPI->transfer(LINK_RAW_WIRELESS_DATA_REQUEST);
|
||||
if (!reverseAcknowledge()) {
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
reset();
|
||||
return remoteCommand;
|
||||
}
|
||||
remoteCommand.params.push_back(paramData);
|
||||
log("<< " + toHex(paramData));
|
||||
}
|
||||
|
||||
log("sending ack");
|
||||
command = linkSPI->transfer(0x99660000 | ((commandId + 0x80) & 0xff));
|
||||
if (!reverseAcknowledge()) {
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
reset();
|
||||
return remoteCommand;
|
||||
}
|
||||
|
||||
if (command != LINK_RAW_WIRELESS_DATA_REQUEST) {
|
||||
log("! expected cmd request");
|
||||
log("! but received 0x" + toHex(command));
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
reset();
|
||||
return remoteCommand;
|
||||
}
|
||||
|
||||
log("setting SPI to 2Mbps");
|
||||
linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS);
|
||||
|
||||
remoteCommand.success = true;
|
||||
remoteCommand.commandId = commandId;
|
||||
|
||||
return remoteCommand;
|
||||
}
|
||||
|
||||
u32 getDeviceTransferLength() {
|
||||
return state == SERVING ? LINK_RAW_WIRELESS_MAX_COMMAND_TRANSFER_LENGTH
|
||||
: LINK_RAW_WIRELESS_MAX_CLIENT_TRANSFER_LENGTH;
|
||||
|
|
@ -695,6 +789,21 @@ class LinkRawWireless {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool reverseAcknowledge() {
|
||||
u32 lines = 0;
|
||||
u32 vCount = REG_VCOUNT;
|
||||
|
||||
while (!linkSPI->_isSIHigh()) {
|
||||
if (cmdTimeout(lines, vCount)) {
|
||||
log("! REV_ACK failed. I put SO=HIGH,");
|
||||
log("! but SI didn't become HIGH.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmdTimeout(u32& lines, u32& vCount) {
|
||||
return timeout(LINK_RAW_WIRELESS_CMD_TIMEOUT, lines, vCount);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user