diff --git a/README.md b/README.md index 45e9f83..a8a3359 100644 --- a/README.md +++ b/README.md @@ -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)! \ No newline at end of file +⚠️ only use the 2Mbps mode with custom hardware (very short wires)! + +⚠️ don't send 0xFFFFFFFF, it's reserved for errors! \ No newline at end of file diff --git a/examples/LinkCableMultiBoot_demo/src/main.cpp b/examples/LinkCableMultiBoot_demo/src/main.cpp index 155ebad..236961b 100644 --- a/examples/LinkCableMultiBoot_demo/src/main.cpp +++ b/examples/LinkCableMultiBoot_demo/src/main.cpp @@ -118,11 +118,11 @@ int main() { } else { output += std::string("Waiting... "); } - log(output); linkCable->consume(); VBlankIntrWait(); + log(output); } return 0; diff --git a/examples/LinkCable_basic/src/main.cpp b/examples/LinkCable_basic/src/main.cpp index e5d8097..00c337f 100644 --- a/examples/LinkCable_basic/src/main.cpp +++ b/examples/LinkCable_basic/src/main.cpp @@ -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; diff --git a/examples/LinkCable_stress/src/main.cpp b/examples/LinkCable_stress/src/main.cpp index 72caebf..b46a77d 100644 --- a/examples/LinkCable_stress/src/main.cpp +++ b/examples/LinkCable_stress/src/main.cpp @@ -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; diff --git a/examples/LinkGPIO_demo/src/main.cpp b/examples/LinkGPIO_demo/src/main.cpp index dbcda05..73ac4ba 100644 --- a/examples/LinkGPIO_demo/src/main.cpp +++ b/examples/LinkGPIO_demo/src/main.cpp @@ -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; diff --git a/examples/LinkSPI_demo/src/main.cpp b/examples/LinkSPI_demo/src/main.cpp index 767be70..ba47d18 100644 --- a/examples/LinkSPI_demo/src/main.cpp +++ b/examples/LinkSPI_demo/src/main.cpp @@ -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; diff --git a/lib/LinkSPI.h b/lib/LinkSPI.h index 8eb281f..16f1c3b 100644 --- a/lib/LinkSPI.h +++ b/lib/LinkSPI.h @@ -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 #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 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; }