mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-09-07 08:26:40 -05:00
Fixing LinkSPI edge cases
This commit is contained in:
@@ -128,4 +128,6 @@ Name | Return type | Description
|
||||
|
||||
⚠️ when using Normal Mode between two GBAs, use a GBC Link Cable!
|
||||
|
||||
⚠️ only use the 2Mbps mode with custom hardware (very short wires)!
|
||||
⚠️ only use the 2Mbps mode with custom hardware (very short wires)!
|
||||
|
||||
⚠️ don't send 0xFFFFFFFF, it's reserved for errors!
|
||||
@@ -118,11 +118,11 @@ int main() {
|
||||
} else {
|
||||
output += std::string("Waiting... ");
|
||||
}
|
||||
log(output);
|
||||
|
||||
linkCable->consume();
|
||||
|
||||
VBlankIntrWait();
|
||||
log(output);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -62,12 +62,12 @@ int main() {
|
||||
} else {
|
||||
output += std::string("Waiting...");
|
||||
}
|
||||
log(output);
|
||||
|
||||
// (5) Mark the current state copy (front buffer) as consumed
|
||||
linkCable->consume();
|
||||
|
||||
VBlankIntrWait();
|
||||
log(output);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -62,22 +62,21 @@ int main() {
|
||||
output += "(" + std::to_string(localCounter) + ", " +
|
||||
std::to_string(remoteCounter) + ")\n";
|
||||
} else {
|
||||
output += std::string("Waiting...");
|
||||
output += "Waiting...";
|
||||
localCounter = 0;
|
||||
remoteCounter = 0;
|
||||
error = false;
|
||||
}
|
||||
|
||||
linkCable->consume();
|
||||
|
||||
VBlankIntrWait();
|
||||
log(output);
|
||||
|
||||
if (error) {
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
|
||||
linkCable->consume();
|
||||
|
||||
VBlankIntrWait();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -15,6 +15,9 @@ void init() {
|
||||
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0;
|
||||
tte_init_se_default(0, BG_CBB(0) | BG_SBB(31));
|
||||
|
||||
irq_init(NULL);
|
||||
irq_add(II_VBLANK, NULL);
|
||||
|
||||
// (2) Initialize the library
|
||||
linkGPIO->reset();
|
||||
}
|
||||
@@ -53,9 +56,6 @@ int main() {
|
||||
output += value("SD", LinkGPIO::Pin::SD, sendSDHigh);
|
||||
output += value("SC", LinkGPIO::Pin::SC, sendSCHigh);
|
||||
|
||||
// Print
|
||||
log(output);
|
||||
|
||||
// Set modes
|
||||
if (setSOOutput)
|
||||
linkGPIO->setMode(LinkGPIO::Pin::SO, LinkGPIO::Direction::OUTPUT);
|
||||
@@ -78,10 +78,9 @@ int main() {
|
||||
if (linkGPIO->getMode(LinkGPIO::Pin::SC) == LinkGPIO::Direction::OUTPUT)
|
||||
linkGPIO->writePin(LinkGPIO::Pin::SC, sendSCHigh);
|
||||
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
// Print
|
||||
VBlankIntrWait();
|
||||
log(output);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -12,6 +12,9 @@ LinkSPI* linkSPI = new LinkSPI();
|
||||
void init() {
|
||||
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0;
|
||||
tte_init_se_default(0, BG_CBB(0) | BG_SBB(31));
|
||||
|
||||
irq_init(NULL);
|
||||
irq_add(II_VBLANK, NULL);
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -27,8 +30,9 @@ int main() {
|
||||
firstTransfer = true;
|
||||
output += "START: Set as Master\n";
|
||||
output += "SELECT: Set as Slave\n";
|
||||
output += "\n(stop: L+R)\n";
|
||||
output +=
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[!] to test this demo...\n "
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n[!] to test this demo...\n "
|
||||
"...use a GBC Link Cable!";
|
||||
|
||||
if ((keys & KEY_START) | (keys & KEY_SELECT)) {
|
||||
@@ -40,9 +44,8 @@ int main() {
|
||||
} else {
|
||||
// Title
|
||||
auto modeName =
|
||||
linkSPI->getMode() == LinkSPI::Mode::SLAVE ? "Slave" : "Master";
|
||||
output += std::string("[") + modeName + "]\n";
|
||||
output += "(stop: L+R)\n\n";
|
||||
linkSPI->getMode() == LinkSPI::Mode::SLAVE ? "[slave]" : "[master]";
|
||||
output += std::string(modeName) + "\n";
|
||||
if (firstTransfer)
|
||||
log(output + "Waiting...");
|
||||
|
||||
@@ -51,8 +54,8 @@ int main() {
|
||||
u16 keys = ~REG_KEYS & KEY_ANY;
|
||||
return (keys & KEY_L) && (keys & KEY_R);
|
||||
});
|
||||
output += "local: " + std::to_string(keys) + "\n";
|
||||
output += "remote: " + std::to_string(remoteKeys) + "\n";
|
||||
output += "> " + std::to_string(keys) + "\n";
|
||||
output += "< " + std::to_string(remoteKeys) + "\n";
|
||||
firstTransfer = false;
|
||||
|
||||
// Cancel
|
||||
@@ -61,12 +64,8 @@ int main() {
|
||||
}
|
||||
|
||||
// Print
|
||||
VBlankIntrWait();
|
||||
log(output);
|
||||
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -22,15 +22,13 @@
|
||||
// considerations:
|
||||
// - when using Normal Mode between two GBAs, use a GBC Link Cable!
|
||||
// - only use the 2Mbps mode with custom hardware (very short wires)!
|
||||
// - don't send 0xFFFFFFFF, it's reserved for errors!
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <tonc_core.h>
|
||||
|
||||
#define LINK_SPI_CANCELED 0xffffffff
|
||||
#define LINK_SPI_RCNT_NORMAL 0
|
||||
#define LINK_SPI_SIOCNT_NORMAL 0
|
||||
#define LINK_SPI_RCNT_GENERAL_PURPOSE (1 << 15)
|
||||
#define LINK_SPI_SIOCNT_GENERAL_PURPOSE 0
|
||||
#define LINK_SPI_BIT_CLOCK 0
|
||||
#define LINK_SPI_BIT_CLOCK_SPEED 1
|
||||
#define LINK_SPI_BIT_SI 2
|
||||
@@ -38,6 +36,8 @@
|
||||
#define LINK_SPI_BIT_START 7
|
||||
#define LINK_SPI_BIT_LENGTH 12
|
||||
#define LINK_SPI_BIT_IRQ 14
|
||||
#define LINK_SPI_BIT_GENERAL_PURPOSE_LOW 14
|
||||
#define LINK_SPI_BIT_GENERAL_PURPOSE_HIGH 15
|
||||
#define LINK_SPI_SET_HIGH(REG, BIT) REG |= 1 << BIT
|
||||
#define LINK_SPI_SET_LOW(REG, BIT) REG &= ~(1 << BIT)
|
||||
|
||||
@@ -53,6 +53,7 @@ class LinkSPI {
|
||||
|
||||
setNormalMode();
|
||||
set32BitPackets();
|
||||
disableTransfer();
|
||||
|
||||
if (mode == SLAVE)
|
||||
setSlaveMode();
|
||||
@@ -65,7 +66,6 @@ class LinkSPI {
|
||||
set2MbpsSpeed();
|
||||
}
|
||||
|
||||
disableTransfer();
|
||||
isEnabled = true;
|
||||
}
|
||||
|
||||
@@ -82,21 +82,23 @@ class LinkSPI {
|
||||
|
||||
template <typename F>
|
||||
u32 transfer(u32 data, F cancel) {
|
||||
if (isEnabled && isMaster())
|
||||
activate(mode);
|
||||
|
||||
setData(data);
|
||||
enableTransfer();
|
||||
|
||||
while (isMaster() && waitMode && !isSlaveReady())
|
||||
if (cancel())
|
||||
if (cancel()) {
|
||||
disableTransfer();
|
||||
return LINK_SPI_CANCELED;
|
||||
}
|
||||
|
||||
startTransfer();
|
||||
|
||||
while (!isReady())
|
||||
if (cancel())
|
||||
if (cancel()) {
|
||||
stopTransfer();
|
||||
disableTransfer();
|
||||
return LINK_SPI_CANCELED;
|
||||
}
|
||||
|
||||
disableTransfer();
|
||||
return getData();
|
||||
@@ -111,13 +113,13 @@ class LinkSPI {
|
||||
bool isEnabled = false;
|
||||
|
||||
void setNormalMode() {
|
||||
REG_RCNT = LINK_SPI_RCNT_NORMAL;
|
||||
LINK_SPI_SET_LOW(REG_RCNT, LINK_SPI_BIT_GENERAL_PURPOSE_HIGH);
|
||||
REG_SIOCNT = LINK_SPI_SIOCNT_NORMAL;
|
||||
}
|
||||
|
||||
void setGeneralPurposeMode() {
|
||||
REG_RCNT = LINK_SPI_RCNT_GENERAL_PURPOSE;
|
||||
REG_SIOCNT = LINK_SPI_SIOCNT_GENERAL_PURPOSE;
|
||||
LINK_SPI_SET_LOW(REG_RCNT, LINK_SPI_BIT_GENERAL_PURPOSE_LOW);
|
||||
LINK_SPI_SET_HIGH(REG_RCNT, LINK_SPI_BIT_GENERAL_PURPOSE_HIGH);
|
||||
}
|
||||
|
||||
void setData(u32 data) { REG_SIODATA32 = data; }
|
||||
|
||||
Reference in New Issue
Block a user