Fixing LinkSPI edge cases

This commit is contained in:
Rodrigo Alfonso
2023-01-30 00:36:56 -03:00
parent c8e639ff8f
commit 0be474b239
7 changed files with 39 additions and 38 deletions

View File

@@ -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!

View File

@@ -118,11 +118,11 @@ int main() {
} else {
output += std::string("Waiting... ");
}
log(output);
linkCable->consume();
VBlankIntrWait();
log(output);
}
return 0;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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; }