From 705355d12eaedc97861b149682fd7bf9e603edfd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 3 Sep 2022 00:04:30 +0200 Subject: [PATCH] there are problems with this scheduler thing. committing it anyway --- src/Wifi.cpp | 187 +++++++++++++++++++++++++++++++++++++++++-------- src/Wifi.h | 3 +- src/WifiAP.cpp | 2 +- 3 files changed, 159 insertions(+), 33 deletions(-) diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 39cfe5de..c07a7eb3 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -84,6 +84,7 @@ struct TXSlot u16 Addr; u16 Length; u8 Rate; + u32 Preamble; u8 CurPhase; u32 CurPhaseTime; u32 HalfwordTimeMask; @@ -170,6 +171,9 @@ void TRX_Next(); void TXPhase_Start(u32 num); void TXPhase_Finish(u32 num); +void TXPhase_MP_RXReply(u32 nclient); +void TXPhase_MP_StartAck(u32 param); +void TXPhase_MP_FinishAck(u32 param); void StartTX_Beacon(); void PeriodicRXCheck(u32 time); @@ -681,8 +685,7 @@ void StartTX_LocN(int nslot, int loc) if (rate == 0x14) slot->Rate = 2; else slot->Rate = 1; - slot->CurPhase = 0; - slot->CurPhaseTime = PreambleLen(slot->Rate); + slot->Preamble = PreambleLen(slot->Rate); } void StartTX_Cmd() @@ -701,8 +704,7 @@ void StartTX_Cmd() if (rate == 0x14) slot->Rate = 2; else slot->Rate = 1; - slot->CurPhase = 0; - slot->CurPhaseTime = PreambleLen(slot->Rate); + slot->Preamble = PreambleLen(slot->Rate); } void StartTX_Beacon() @@ -716,8 +718,7 @@ void StartTX_Beacon() if (rate == 0x14) slot->Rate = 2; else slot->Rate = 1; - slot->CurPhase = 0; - slot->CurPhaseTime = PreambleLen(slot->Rate); + slot->Preamble = PreambleLen(slot->Rate); IOPORT(W_TXBusy) |= 0x0010; } @@ -854,7 +855,7 @@ void SendMPReply(u16 clienttime, u16 clientmask) clientnum++; } - slot->CurPhaseTime = 16 + ((clienttime + 10) * clientnum) + PreambleLen(slot->Rate); + slot->Preamble = 16 + ((clienttime + 10) * clientnum) + PreambleLen(slot->Rate); IOPORT(W_TXBusy) |= 0x0080; } @@ -1199,13 +1200,27 @@ bool ProcessTX(TXSlot* slot, int num) void TXPhase_Start(u32 num) -{printf("TX start %d\n", num); +{ TXSlot* slot = &TXSlots[num]; SetIRQ(7); if (num == 5) + { SetStatus(8); + + if (!slot->Valid) + { + // if this is a default empty reply: we don't need to do all the setup + + u32 len = 28; + if (slot->Rate == 2) len *= 4; + else len *= 8; + + ScheduleEvent(Event_TX, true, len, TXPhase_Finish, num); + return; + } + } else SetStatus(3); @@ -1266,14 +1281,23 @@ void TXPhase_Start(u32 num) u32 len = slot->Length; if (slot->Rate == 2) len *= 4; else len *= 8; -printf("scheduling TX finish, slot=%d\n", num); - ScheduleEvent(Event_TRX, false, len, TXPhase_Finish, num); + + ScheduleEvent(Event_TX, true, len, TXPhase_Finish, num); } void TXPhase_Finish(u32 num) -{printf("TX finish %d\n", num); +{ TXSlot* slot = &TXSlots[num]; + if ((num == 5) && (!slot->Valid)) + { + IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF; + + IOPORT(W_TXBusy) &= ~0x80; + TRX_Next(); + return; + } + // for the MP CMD and reply slots, this is set later if (num != 1 && num != 5) *(u16*)&RAM[slot->Addr] = 0x0001; @@ -1290,7 +1314,7 @@ void TXPhase_Finish(u32 num) u16 clientmask = *(u16*)&RAM[slot->Addr + 12 + 24 + 2]; //MPNumReplies = NumClients(clientmask); - MPReplyTimer = 16 + PreambleLen(slot->Rate); + //MPReplyTimer = 16 + PreambleLen(slot->Rate); MPClientMask = clientmask; MPClientFail = clientmask; @@ -1302,7 +1326,19 @@ void TXPhase_Finish(u32 num) /*slot->CurPhase = 2; slot->CurPhaseTime = 112 + ((10 + IOPORT(W_CmdReplyTime)) * NumClients(clientmask)); aaaaaaaaaaaaaaaaaaaaaaa*/ - printf("MP CMD SHITO TODO\n"); + //printf("MP CMD SHITO TODO\n"); + // slot->Preamble = 16 + ((clienttime + 10) * clientnum) + PreambleLen(slot->Rate); + // 16 + ((10 + IOPORT(W_CmdReplyTime)) * NumClients(clientmask)) + preamble(ack); + if (MPClientMask) + { + int nclient = 1; + while (!(MPClientMask & (1 << nclient))) nclient++; + ScheduleEvent(Event_TX, true, 16+PreambleLen(slot->Rate), TXPhase_MP_RXReply, nclient); + } + else + { + ScheduleEvent(Event_TX, true, 16+PreambleLen(slot->Rate), TXPhase_MP_StartAck, 0); + } return; } @@ -1343,6 +1379,91 @@ void TXPhase_Finish(u32 num) TRX_Next(); } +void TXPhase_MP_RXReply(u32 nclient) +{ + TXSlot* slot = &TXSlots[1]; + + u32 curclient = 1 << nclient; + + /*if (CheckRX(1)) + { + // we received a reply, mark it as such + // TODO: is any received packet considered a good reply? + // hardware probably requires a specific frame-control and/or destination MAC + + MPClientFail &= ~curclient; + } + else printf("REPLY %04X NOT RECEIVED\n");*/ + if (!(MPClientFail & curclient)) + MPClientReplyRX(nclient); + + //MPReplyTimer = 10 + IOPORT(W_CmdReplyTime); + MPClientMask &= ~curclient; + if (MPClientMask) + { + do { nclient++; } while (!(MPClientMask & (1 << nclient))); + ScheduleEvent(Event_TX, true, 10+IOPORT(W_CmdReplyTime), TXPhase_MP_RXReply, nclient); + } + else + { + ScheduleEvent(Event_TX, true, 10+IOPORT(W_CmdReplyTime), TXPhase_MP_StartAck, 0); + } +} + +void TXPhase_MP_StartAck(u32 param) +{ + TXSlot* slot = &TXSlots[1]; + + SetIRQ(7); + SetStatus(8); + + IOPORT(W_RXTXAddr) = 0xFC0; + + ReportMPReplyErrors(MPClientFail); + + // send + SendMPAck(MPClientFail); + + u32 len = 32; + if (slot->Rate == 2) len *= 4; + else len *= 8; + + ScheduleEvent(Event_TX, true, len, TXPhase_MP_FinishAck, 0); +} + +void TXPhase_MP_FinishAck(u32 param) +{ + TXSlot* slot = &TXSlots[1]; + + // checkme + IOPORT(W_TXBusy) &= ~(1<<1); + IOPORT(W_TXSlotCmd) &= 0x7FFF; // confirmed + + if (!MPClientFail) + *(u16*)&RAM[slot->Addr] = 0x0001; + else + *(u16*)&RAM[slot->Addr] = 0x0005; + + // this is set to indicate which clients failed to reply + *(u16*)&RAM[slot->Addr + 0x2] = MPClientFail; + IncrementTXCount(slot); + + IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF; + + if (IOPORT(W_TXStatCnt) & 0x2000) + { + IOPORT(W_TXStat) = 0x0B01; + SetIRQ(1); + } + + // TODO: retry the whole cycle if some clients failed to respond + // AND if there is enough time left in CMDCOUNT + // (games seem to always configure CMDCOUNT such that there is no time for retries) + SetIRQ(12); + + TRX_Next(); +} + void TRX_Next() { @@ -1354,13 +1475,17 @@ void TRX_Next() return; } - if ((!IsMPClient) || (USTimestamp > NextSync)) + u16 txbusy = IOPORT(W_TXBusy); + + if (!(txbusy & 0x0080)) { - if (CheckRX(0)) - return; + if ((!IsMPClient) || (USTimestamp > NextSync)) + { + if (CheckRX(0)) + return; + } } - u16 txbusy = IOPORT(W_TXBusy); if (txbusy) {u32 dorp = ComStatus; ComStatus = 0x2; @@ -1372,11 +1497,11 @@ void TRX_Next() else if (txbusy & 0x0004) slot = 2; else if (txbusy & 0x0002) slot = 1; else if (txbusy & 0x0001) slot = 0; -printf("scheduling TX, slot=%d, comstatus=%d\n", slot, dorp); - ScheduleEvent(Event_TRX, false, PreambleLen(TXSlots[slot].Rate), TXPhase_Start, slot); + + ScheduleEvent(Event_TX, false, TXSlots[slot].Preamble, TXPhase_Start, slot); return; } -printf("TRX_Next: nothing to do\n"); + ComStatus = 0; SetStatus(1); } @@ -1393,7 +1518,7 @@ inline void IncrementRXAddr(u16& addr, u16 inc = 2) } } -void StartRX(u32 param) +void StartRX(u32 type) { u16 framelen = *(u16*)&RXBuffer[8]; u32 frametime = framelen; @@ -1414,8 +1539,8 @@ void StartRX(u32 param) RXStartTime = SchedTimestamp; RXCount = 0; -printf("scheduling RX end\n"); - ScheduleEvent(Event_TRX, false, frametime, FinishRX, 0); + + ScheduleEvent(Event_RX, false, frametime, FinishRX, type); } void AdvanceRX() @@ -1453,8 +1578,8 @@ void AdvanceRX() RXCount += ndata; } -void FinishRX(u32 param) -{printf("finish RX\n"); +void FinishRX(u32 type) +{ AdvanceRX(); u16 addr = IOPORT(W_RXTXAddr) << 1; @@ -1510,7 +1635,7 @@ void FinishRX(u32 param) USCounter = timestamp; } - TRX_Next(); + if (type == 0) TRX_Next(); } void MPClientReplyRX(int client) @@ -1619,7 +1744,7 @@ void MPClientReplyRX(int client) *(u16*)&RXBuffer[10] = 0x4080; // min/max RSSI. dunno //RXTimestamp = 0; - StartRX(0); + StartRX(1); } bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames @@ -1632,7 +1757,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames if (IOPORT(W_RXBufBegin) == IOPORT(W_RXBufEnd)) return false; - +if (IsMPClient) printf("CheckRX(%d)\n", type); int rxlen; u16 framelen; u16 framectl; @@ -1750,7 +1875,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames WIFI_LOG("wifi: received packet FC:%04X SN:%04X CL:%04X RXT:%d CMT:%d\n", framectl, *(u16*)&RXBuffer[12+4+6+6+6], *(u16*)&RXBuffer[12+4+6+6+6+2+2], framelen*4, IOPORT(W_CmdReplyTime)); -printf("checkRX: got frame\n"); + // make RX header /*if ((rxflags&0xF)==0xD) @@ -1814,7 +1939,7 @@ printf("checkRX: got frame\n"); else { u32 delay = (u32)(rxtime - USTimestamp); - ScheduleEvent(Event_TRX, false, delay, StartRX, 0); + ScheduleEvent(Event_RX, false, delay, StartRX, 0); } NextSync = rxtime + (framelen * (txrate==0x14 ? 4:8)); @@ -1898,7 +2023,7 @@ void MSTimer(u32 param) IOPORT(W_BeaconCount2)--; if (IOPORT(W_BeaconCount2) == 0) SetIRQ13(); } -//printf("MSTimer %016llX %016llX\n", SchedTimestamp, USCounter); + ScheduleEvent(Event_MSTimer, true, 1024, MSTimer, 0); } diff --git a/src/Wifi.h b/src/Wifi.h index 46cf1bd9..89a23dae 100644 --- a/src/Wifi.h +++ b/src/Wifi.h @@ -157,7 +157,8 @@ enum Event_IRQ15, Event_MSTimer, Event_RFWakeup, - Event_TRX, + Event_RX, + Event_TX, Event_MPClientSync, Event_RF, Event_BB, diff --git a/src/WifiAP.cpp b/src/WifiAP.cpp index 92901539..53516396 100644 --- a/src/WifiAP.cpp +++ b/src/WifiAP.cpp @@ -91,7 +91,7 @@ void DeInit() void Reset() { // random starting point for the counter - USCounter = 0x428888017ULL; + USCounter = 0x428888000ULL; SeqNo = 0x0120; BeaconDue = false;