Skip to content

Commit

Permalink
LinkWireless: deprecating asyncACKTimerId. With last changes, it's no…
Browse files Browse the repository at this point in the history
…t needed and actually burns more cycles
  • Loading branch information
afska committed Aug 27, 2024
1 parent 57a818d commit 44453da
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 221 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ Name | Type | Default | Description
`timeout` | **u32** | `10` | Maximum number of *frames* without receiving data from other player before resetting the connection.
`interval` | **u16** | `50` | Number of *1024-cycle ticks* (61.04μs) between transfers *(50 = 3.052ms)*. It's the interval of Timer #`sendTimerId`. Lower values will transfer faster but also consume more CPU. You can use `Link::perFrame(...)` to convert from *packets per frame* to *interval values*.
`sendTimerId` | **u8** *(0~3)* | `3` | GBA Timer to use for sending.
`asyncACKTimerId` | **s8** *(0~3 or -1)* | `-1` | This GBA timer is used to asynchronously acknowledge the adapter transfers. It is disabled by default, with the acknowledgment procedure performed during SERIAL interrupts.
You can update these values at any time without creating a new instance:
- Call `deactivate()`.
Expand Down
5 changes: 1 addition & 4 deletions examples/LinkCable_stress/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ LinkUniversal* linkUniversal =
.maxPlayers = 2,
.timeout = LINK_WIRELESS_DEFAULT_TIMEOUT,
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
.asyncACKTimerId = 0},
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID},
__qran_seed);
LinkUniversal* linkConnection = linkUniversal;
#endif
Expand All @@ -76,8 +75,6 @@ void init() {
interrupt_enable(INTR_SERIAL);
interrupt_set_handler(INTR_TIMER3, LINK_UNIVERSAL_ISR_TIMER);
interrupt_enable(INTR_TIMER3);
interrupt_set_handler(INTR_TIMER0, LINK_UNIVERSAL_ISR_ACK_TIMER);
interrupt_enable(INTR_TIMER0);
#endif
}

Expand Down
29 changes: 14 additions & 15 deletions examples/LinkUniversal_basic/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,20 @@ int main() {
u32 maxPlayers = (initialKeys & KEY_B) ? 2 : LINK_UNIVERSAL_MAX_PLAYERS;

// (1) Create a LinkUniversal instance
linkUniversal = new LinkUniversal(
protocol, "LinkUNI",
(LinkUniversal::CableOptions){
.baudRate = LinkCable::BAUD_RATE_1,
.timeout = LINK_CABLE_DEFAULT_TIMEOUT,
.interval = LINK_CABLE_DEFAULT_INTERVAL,
.sendTimerId = LINK_CABLE_DEFAULT_SEND_TIMER_ID},
(LinkUniversal::WirelessOptions){
.retransmission = true,
.maxPlayers = maxPlayers,
.timeout = LINK_WIRELESS_DEFAULT_TIMEOUT,
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
.asyncACKTimerId = LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID},
__qran_seed);
linkUniversal =
new LinkUniversal(protocol, "LinkUNI",
(LinkUniversal::CableOptions){
.baudRate = LinkCable::BAUD_RATE_1,
.timeout = LINK_CABLE_DEFAULT_TIMEOUT,
.interval = LINK_CABLE_DEFAULT_INTERVAL,
.sendTimerId = LINK_CABLE_DEFAULT_SEND_TIMER_ID},
(LinkUniversal::WirelessOptions){
.retransmission = true,
.maxPlayers = maxPlayers,
.timeout = LINK_WIRELESS_DEFAULT_TIMEOUT,
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID},
__qran_seed);

// (2) Add the required interrupt service routines
interrupt_init();
Expand Down
24 changes: 5 additions & 19 deletions examples/LinkWireless_demo/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void hang();

LinkWireless::Error lastError;
LinkWireless* linkWireless = nullptr;
bool forwarding, retransmission, asyncACK;
bool forwarding, retransmission;
u32 maxPlayers;

void init() {
Expand Down Expand Up @@ -69,20 +69,17 @@ int main() {
"Press A to start\n\n"
"hold LEFT on start:\n -> disable forwarding\n\n"
"hold UP on start:\n -> disable retransmission\n\n"
"hold B on start:\n -> set 2 players\n\n"
"hold START on start:\n -> async ACK");
"hold B on start:\n -> set 2 players");
waitFor(KEY_A);
u16 initialKeys = ~REG_KEYS & KEY_ANY;
forwarding = !(initialKeys & KEY_LEFT);
retransmission = !(initialKeys & KEY_UP);
maxPlayers = (initialKeys & KEY_B) ? 2 : LINK_WIRELESS_MAX_PLAYERS;
asyncACK = initialKeys & KEY_START;

// (1) Create a LinkWireless instance
linkWireless = new LinkWireless(
forwarding, retransmission, maxPlayers, LINK_WIRELESS_DEFAULT_TIMEOUT,
LINK_WIRELESS_DEFAULT_INTERVAL, LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
asyncACK ? 0 : -1);
LINK_WIRELESS_DEFAULT_INTERVAL, LINK_WIRELESS_DEFAULT_SEND_TIMER_ID);
// linkWireless->debug = [](std::string str) { log(str); };

// (2) Add the required interrupt service routines
Expand All @@ -94,10 +91,6 @@ int main() {
interrupt_set_handler(INTR_TIMER3, LINK_WIRELESS_ISR_TIMER);
interrupt_enable(INTR_TIMER3);

// (only required when using async ACK)
interrupt_set_handler(INTR_TIMER0, LINK_WIRELESS_ISR_ACK_TIMER);
interrupt_enable(INTR_TIMER0);

// (3) Initialize the library
linkWireless->activate();

Expand All @@ -114,8 +107,7 @@ int main() {
"(SELECT = cancel)\n (START = activate)\n\n-> forwarding: " +
(forwarding ? "ON" : "OFF") +
"\n-> retransmission: " + (retransmission ? "ON" : "OFF") +
"\n-> max players: " + std::to_string(maxPlayers) +
"\n-> async ACK: " + (asyncACK ? "ON" : "OFF"));
"\n-> max players: " + std::to_string(maxPlayers));

// SELECT = back
if (keys & KEY_SELECT) {
Expand Down Expand Up @@ -431,22 +423,16 @@ void messageLoop() {
output += "\n_onVBlank: " + std::to_string(linkWireless->lastVBlankTime);
output += "\n_onSerial: " + std::to_string(linkWireless->lastSerialTime);
output += "\n_onTimer: " + std::to_string(linkWireless->lastTimerTime);
if (asyncACK)
output += " | " + std::to_string(linkWireless->lastACKTimerTime);
output +=
"\n_serialIRQs: " + std::to_string(linkWireless->lastFrameSerialIRQs);
output +=
"\n_timerIRQs: " + std::to_string(linkWireless->lastFrameTimerIRQs);
if (asyncACK)
output += " | " + std::to_string(linkWireless->lastFrameACKTimerIRQs);
output +=
"\n_ms: " +
std::to_string(linkWireless->toMs(
linkWireless->lastVBlankTime +
linkWireless->lastSerialTime * linkWireless->lastFrameSerialIRQs +
linkWireless->lastTimerTime * linkWireless->lastFrameTimerIRQs +
linkWireless->lastACKTimerTime *
linkWireless->lastFrameACKTimerIRQs));
linkWireless->lastTimerTime * linkWireless->lastFrameTimerIRQs));
#else
if (lostPackets > 0) {
output += "\n\n_lostPackets: " + std::to_string(lostPackets) + "\n";
Expand Down
24 changes: 2 additions & 22 deletions lib/LinkUniversal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
// irq_add(II_VBLANK, LINK_UNIVERSAL_ISR_VBLANK);
// irq_add(II_SERIAL, LINK_UNIVERSAL_ISR_SERIAL);
// irq_add(II_TIMER3, LINK_UNIVERSAL_ISR_TIMER);
// irq_add(II_TIMER2, LINK_UNIVERSAL_ISR_ACK_TIMER); // (*)
// // optional, for `LinkWireless::asyncACKTimerId` -----^
// - 3) Initialize the library with:
// linkUniversal->activate();
// - 4) Sync:
Expand Down Expand Up @@ -120,7 +118,6 @@ class LinkUniversal {
u32 timeout;
u16 interval;
u8 sendTimerId;
s8 asyncACKTimerId;
};

/**
Expand All @@ -147,8 +144,7 @@ class LinkUniversal {
true, LINK_UNIVERSAL_MAX_PLAYERS,
LINK_WIRELESS_DEFAULT_TIMEOUT,
LINK_WIRELESS_DEFAULT_INTERVAL,
LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID},
LINK_WIRELESS_DEFAULT_SEND_TIMER_ID},
int randomSeed = 123) {
this->linkCable =
new LinkCable(cableOptions.baudRate, cableOptions.timeout,
Expand All @@ -157,7 +153,7 @@ class LinkUniversal {
wirelessOptions.retransmission, true,
Link::_min(wirelessOptions.maxPlayers, LINK_UNIVERSAL_MAX_PLAYERS),
wirelessOptions.timeout, wirelessOptions.interval,
wirelessOptions.sendTimerId, wirelessOptions.asyncACKTimerId);
wirelessOptions.sendTimerId);

this->config.protocol = protocol;
this->config.gameName = gameName;
Expand Down Expand Up @@ -440,15 +436,6 @@ class LinkUniversal {
linkWireless->_onTimer();
}

/**
* @brief This method is called by the other TIMER interrupt handler.
* \warning This is internal API!
*/
void _onACKTimer() {
if (mode == LINK_WIRELESS)
linkWireless->_onACKTimer();
}

LinkCable* linkCable;
LinkWireless* linkWireless;

Expand Down Expand Up @@ -712,11 +699,4 @@ inline void LINK_UNIVERSAL_ISR_TIMER() {
linkUniversal->_onTimer();
}

/**
* @brief TIMER interrupt handler used for ACKs.
*/
inline void LINK_UNIVERSAL_ISR_ACK_TIMER() {
linkUniversal->_onACKTimer();
}

#endif // LINK_UNIVERSAL_H
16 changes: 0 additions & 16 deletions lib/LinkWireless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,6 @@ LINK_WIRELESS_CODE_IWRAM void LinkWireless::_onTimer() {

__onTimer();

#ifdef LINK_WIRELESS_ENABLE_NESTED_IRQ
irqEnd();
#endif
}
LINK_WIRELESS_CODE_IWRAM void LinkWireless::_onACKTimer() {
#ifdef LINK_WIRELESS_ENABLE_NESTED_IRQ
if (interrupt)
return;

interrupt = true;
LINK_WIRELESS_BARRIER;
Link::_REG_IME = 1;
#endif

__onACKTimer();

#ifdef LINK_WIRELESS_ENABLE_NESTED_IRQ
irqEnd();
#endif
Expand Down
Loading

0 comments on commit 44453da

Please sign in to comment.