diff --git a/README.md b/README.md index 82ba014..38704f9 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Name | Return type | Description `writePin(pin, isHigh)` | - | Sets a `pin` to be high or not (when set as an output). `setSIInterrupts(isEnabled)` | - | If it `isEnabled`, a IRQ will be generated when `SI` changes from *HIGH* to *LOW*. -⚠️ always set the SI terminal to an input! +⚠️ always set the `SI` terminal to an input! # 🔗 LinkSPI diff --git a/examples/LinkWireless_demo/src/main.cpp b/examples/LinkWireless_demo/src/main.cpp index d514e07..60eb8b8 100644 --- a/examples/LinkWireless_demo/src/main.cpp +++ b/examples/LinkWireless_demo/src/main.cpp @@ -10,7 +10,7 @@ void connect(); void messageLoop(bool acceptNewClients); void log(std::string text); void waitFor(u16 key); -void vBlankWait(); +void vBlankWait(); // TODO: VBlankIntrWait(); void hang(); // (1) Create a LinkWireless instance @@ -168,39 +168,40 @@ void connect() { } void messageLoop(bool acceptNewClients) { - u32 i = 50; + u32 i = acceptNewClients ? 50 : 15; bool sending = false; while (true) { u16 keys = ~REG_KEYS & KEY_ANY; - if (!sending && (keys & KEY_A)) { + if (!sending) { sending = true; - linkWireless->sendData(std::vector{1, i}); + bool result = linkWireless->sendDataWait(std::vector{1, i}); + log("Send result: " + std::to_string(result)); i++; - } - if (sending && !(keys & KEY_A)) - sending = false; - if (acceptNewClients) { - auto newConnection = linkWireless->acceptConnection(); - if (!newConnection.success) { - log("Accept failed :("); + std::vector receivedData = std::vector{}; + if (!linkWireless->receiveData(receivedData)) { + log("Receive failed :("); hang(); return; } - if (newConnection.clientIds.size() > 1) - log("New connection: " + std::to_string(newConnection.clientIds[1])); + if (receivedData.size() > 1) + log("<<< " + std::to_string(receivedData[1])); } + if (sending) + sending = false; - std::vector receivedData = std::vector{}; - if (!linkWireless->receiveData(receivedData)) { - log("Receive failed :("); - hang(); - return; - } - if (receivedData.size() > 1) - log("<<< " + std::to_string(receivedData[1])); + // if (acceptNewClients) { + // auto newConnection = linkWireless->acceptConnection(); + // if (!newConnection.success) { + // log("Accept failed :("); + // hang(); + // return; + // } + // if (newConnection.clientIds.size() > 1) + // log("New connection: " + std::to_string(newConnection.clientIds[1])); + // } vBlankWait(); } diff --git a/lib/LinkSPI.h b/lib/LinkSPI.h index 8137e51..dd71969 100644 --- a/lib/LinkSPI.h +++ b/lib/LinkSPI.h @@ -114,7 +114,7 @@ class LinkSPI { setInterruptsOff(); } - enableTransfer(); + // enableTransfer(); while (isMaster() && waitMode && !isSlaveReady()) if (cancel()) { @@ -123,6 +123,7 @@ class LinkSPI { asyncState = IDLE; return LINK_SPI_NO_DATA; } + enableTransfer(); // TODO: MOVE HERE! AND TEST startTransfer(); @@ -180,6 +181,11 @@ class LinkSPI { void _setSOLow() { setBitLow(LINK_SPI_BIT_SO); } bool _isSIHigh() { return isBitHigh(LINK_SPI_BIT_SI); } + // TODO: CHANGE MODE ON THE FLY + void setSlaveMode2() { setBitLow(LINK_SPI_BIT_CLOCK); } + void setMasterMode2() { setBitHigh(LINK_SPI_BIT_CLOCK); } + void set2MbpsSpeed2() { setBitHigh(LINK_SPI_BIT_CLOCK_SPEED); } + private: Mode mode = Mode::SLAVE; bool waitMode = false; diff --git a/lib/LinkWireless.h b/lib/LinkWireless.h index 0fa60a7..7147de3 100644 --- a/lib/LinkWireless.h +++ b/lib/LinkWireless.h @@ -147,7 +147,85 @@ class LinkWireless { return sendCommand(LINK_WIRELESS_COMMAND_SEND_DATA, data).success; } + bool sendDataWait(std::vector data) { + // TODO: IT WORKS RANDOMLY + // TODO: TEST THIS ON BOTH SIDES + + if (!sendCommand(0x25, data).success) // TODO: SEND DATA WAIT + return false; + + linkSPI->setSlaveMode2(); + + u32 command = linkSPI->transfer(LINK_WIRELESS_DATA_REQUEST); + while (!linkSPI->_isSIHigh()) + ; + + if (msB32(command) != LINK_WIRELESS_COMMAND_HEADER) { + debug("NO HEADER: " + std::to_string(command)); + while (true) + ; + linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS); + return false; + } + if (lsB32(command) == 0x0027) { // or 27 = inversion end + command = linkSPI->transfer(0x996600a7); + debug(">> RECEIVED: " + std::to_string(command)); + while (!linkSPI->_isSIHigh()) + ; + if (command != LINK_WIRELESS_DATA_REQUEST) { + debug("NO DATA REQUEST (END): " + std::to_string(command)); + while (true) + ; + linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS); + return false; + } + + linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS); + + wait(LINK_WIRELESS_TRANSFER_WAIT); + return true; + } + + if (lsB32(command) == 0x0128) { + linkSPI->transfer(LINK_WIRELESS_DATA_REQUEST); + while (!linkSPI->_isSIHigh()) + ; + } + + if (lsB32(command) != 0x0128 && + lsB32(command) != 0x0028) { // TODO: WAIT END RESPONSE + debug("NO 28: " + std::to_string(command)); // TODO: OR 29 = disconnected + while (true) + ; + linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS); + return false; + } + + // TODO: WAIT END ACK + command = linkSPI->transfer(0x996600a8); + while (!linkSPI->_isSIHigh()) + ; + linkSPI->_setSOLow(); + + // // TODO: WAIT END ACK + if (command != LINK_WIRELESS_DATA_REQUEST) { + debug("NO WAIT: " + std::to_string(command)); + while (true) + ; + linkSPI->activate(LinkSPI::Mode::MASTER_2MBPS); + return false; + } + + linkSPI->setMasterMode2(); + linkSPI->set2MbpsSpeed2(); + + return true; + } + bool receiveData(std::vector& data) { + if (!sendCommand(0x11).success) // TODO: SIGNAL LEVEL + return false; + auto result = sendCommand(LINK_WIRELESS_COMMAND_RECEIVE_DATA); data = result.responses; return result.success;