add enough TX functionality that online wifi is a possibility again.
This commit is contained in:
parent
e51b8d9997
commit
d04879298c
252
src/Wifi.cpp
252
src/Wifi.cpp
|
@ -166,6 +166,11 @@ void Reschedule();
|
|||
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
|
||||
void CancelEvent(u32 id);
|
||||
|
||||
void TRX_Next();
|
||||
|
||||
void TXPhase_Start(u32 num);
|
||||
void TXPhase_Finish(u32 num);
|
||||
|
||||
void StartTX_Beacon();
|
||||
void PeriodicRXCheck(u32 time);
|
||||
|
||||
|
@ -737,25 +742,23 @@ void FireTX()
|
|||
if (txstart & 0x0008)
|
||||
{
|
||||
StartTX_LocN(3, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (txstart & 0x0004)
|
||||
else if (txstart & 0x0004)
|
||||
{
|
||||
StartTX_LocN(2, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (txstart & 0x0002)
|
||||
else if (txstart & 0x0002)
|
||||
{
|
||||
StartTX_Cmd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (txstart & 0x0001)
|
||||
else if (txstart & 0x0001)
|
||||
{
|
||||
StartTX_LocN(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ComStatus)
|
||||
{
|
||||
TRX_Next();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1198,190 @@ 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);
|
||||
else
|
||||
SetStatus(3);
|
||||
|
||||
u64 oldts;
|
||||
if (num == 4)
|
||||
{
|
||||
// beacon timestamp
|
||||
oldts = *(u64*)&RAM[slot->Addr + 0xC + 24];
|
||||
*(u64*)&RAM[slot->Addr + 0xC + 24] = USCounter;
|
||||
}
|
||||
|
||||
u32 noseqno = 0;
|
||||
if (num == 1) noseqno = (IOPORT(W_TXSlotCmd) & 0x4000);
|
||||
|
||||
if (!noseqno)
|
||||
{
|
||||
*(u16*)&RAM[slot->Addr + 0xC + 22] = IOPORT(W_TXSeqNo) << 4;
|
||||
IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF;
|
||||
}
|
||||
|
||||
// TODO: inhibit seqno adjustment and set framectl.bit11 if txheader[04] is nonzero
|
||||
|
||||
// set TX addr
|
||||
IOPORT(W_RXTXAddr) = slot->Addr >> 1;
|
||||
|
||||
if (num == 1)
|
||||
{
|
||||
// send
|
||||
int txlen = Platform::MP_SendCmd(&RAM[slot->Addr], 12 + slot->Length, USTimestamp);
|
||||
WIFI_LOG("wifi: sent %d/%d bytes of CMD packet, addr=%04X, framectl=%04X, %04X %04X\n",
|
||||
txlen, slot->Length+12, slot->Addr, *(u16*)&RAM[slot->Addr + 0xC],
|
||||
*(u16*)&RAM[slot->Addr + 0x24], *(u16*)&RAM[slot->Addr + 0x26]);
|
||||
}
|
||||
else if (num == 5)
|
||||
{
|
||||
// MP reply frames are handled separately
|
||||
}
|
||||
else
|
||||
{
|
||||
// send
|
||||
int txlen = Platform::MP_SendPacket(&RAM[slot->Addr], 12 + slot->Length, USTimestamp);
|
||||
WIFI_LOG("wifi: sent %d/%d bytes of slot%d packet, addr=%04X, framectl=%04X\n",
|
||||
txlen, slot->Length+12, num, slot->Addr, *(u16*)&RAM[slot->Addr + 0xC]);
|
||||
}
|
||||
|
||||
// if the packet is being sent via LOC1..3, send it to the AP
|
||||
// any packet sent via CMD/REPLY/BEACON isn't going to have much use outside of local MP
|
||||
if (num == 0 || num == 2 || num == 3)
|
||||
{
|
||||
WifiAP::SendPacket(&RAM[slot->Addr], 12 + slot->Length);
|
||||
}
|
||||
|
||||
if (num == 4)
|
||||
{
|
||||
*(u64*)&RAM[slot->Addr + 0xC + 24] = oldts;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void TXPhase_Finish(u32 num)
|
||||
{printf("TX finish %d\n", num);
|
||||
TXSlot* slot = &TXSlots[num];
|
||||
|
||||
// for the MP CMD and reply slots, this is set later
|
||||
if (num != 1 && num != 5)
|
||||
*(u16*)&RAM[slot->Addr] = 0x0001;
|
||||
RAM[slot->Addr + 5] = 0;
|
||||
|
||||
if (num == 1)
|
||||
{
|
||||
if (IOPORT(W_TXStatCnt) & 0x4000)
|
||||
{
|
||||
IOPORT(W_TXStat) = 0x0800;
|
||||
SetIRQ(1);
|
||||
}
|
||||
SetStatus(5);
|
||||
|
||||
u16 clientmask = *(u16*)&RAM[slot->Addr + 12 + 24 + 2];
|
||||
//MPNumReplies = NumClients(clientmask);
|
||||
MPReplyTimer = 16 + PreambleLen(slot->Rate);
|
||||
MPClientMask = clientmask;
|
||||
MPClientFail = clientmask;
|
||||
|
||||
u16 res = Platform::MP_RecvReplies(MPClientReplies, USTimestamp, clientmask);
|
||||
MPClientFail &= ~res;
|
||||
|
||||
// TODO: 112 likely includes the ack preamble, which needs adjusted
|
||||
// for long-preamble settings
|
||||
/*slot->CurPhase = 2;
|
||||
slot->CurPhaseTime = 112 + ((10 + IOPORT(W_CmdReplyTime)) * NumClients(clientmask));
|
||||
aaaaaaaaaaaaaaaaaaaaaaa*/
|
||||
printf("MP CMD SHITO TODO\n");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (num == 5)
|
||||
{
|
||||
if (IOPORT(W_TXStatCnt) & 0x1000)
|
||||
{
|
||||
IOPORT(W_TXStat) = 0x0401;
|
||||
SetIRQ(1);
|
||||
}
|
||||
|
||||
IOPORT(W_TXBusy) &= ~0x80;
|
||||
TRX_Next();
|
||||
return;
|
||||
}
|
||||
|
||||
IOPORT(W_TXBusy) &= ~(1<<num);
|
||||
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
IOPORT(W_TXStat) = 0x0001 | ((num?(num-1):0)<<12);
|
||||
SetIRQ(1);
|
||||
IOPORT(W_TXSlotLoc1 + ((num?(num-1):0)*4)) &= 0x7FFF;
|
||||
break;
|
||||
|
||||
case 4: // beacon
|
||||
if (IOPORT(W_TXStatCnt) & 0x8000)
|
||||
{
|
||||
IOPORT(W_TXStat) = 0x0301;
|
||||
SetIRQ(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
TRX_Next();
|
||||
}
|
||||
|
||||
|
||||
void TRX_Next()
|
||||
{
|
||||
if (IOPORT(W_PowerState) & 0x0300)
|
||||
{
|
||||
// if we are powering down, cancel anything
|
||||
IOPORT(W_TXBusy) = 0;
|
||||
SetStatus(9);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!IsMPClient) || (USTimestamp > NextSync))
|
||||
{
|
||||
if (CheckRX(0))
|
||||
return;
|
||||
}
|
||||
|
||||
u16 txbusy = IOPORT(W_TXBusy);
|
||||
if (txbusy)
|
||||
{u32 dorp = ComStatus;
|
||||
ComStatus = 0x2;
|
||||
|
||||
int slot = -1;
|
||||
if (txbusy & 0x0080) slot = 5;
|
||||
else if (txbusy & 0x0010) slot = 4;
|
||||
else if (txbusy & 0x0008) slot = 3;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
printf("TRX_Next: nothing to do\n");
|
||||
ComStatus = 0;
|
||||
SetStatus(1);
|
||||
}
|
||||
|
||||
|
||||
inline void IncrementRXAddr(u16& addr, u16 inc = 2)
|
||||
{
|
||||
for (u32 i = 0; i < inc; i += 2)
|
||||
|
@ -1212,14 +1399,8 @@ void StartRX(u32 param)
|
|||
u32 frametime = framelen;
|
||||
|
||||
RXRate = *(u16*)&RXBuffer[6];
|
||||
if (RXRate == 0x14)
|
||||
{
|
||||
frametime *= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
frametime *= 8;
|
||||
}
|
||||
if (RXRate == 0x14) frametime *= 4;
|
||||
else frametime *= 8;
|
||||
|
||||
u16 addr = IOPORT(W_RXBufWriteCursor) << 1;
|
||||
IncrementRXAddr(addr, 12);
|
||||
|
@ -1230,10 +1411,10 @@ void StartRX(u32 param)
|
|||
SetIRQ(6);
|
||||
SetStatus(6);
|
||||
ComStatus |= 0x1;
|
||||
printf("start RX\n");
|
||||
|
||||
RXStartTime = SchedTimestamp;
|
||||
RXCount = 0;
|
||||
|
||||
printf("scheduling RX end\n");
|
||||
ScheduleEvent(Event_TRX, false, frametime, FinishRX, 0);
|
||||
}
|
||||
|
||||
|
@ -1251,10 +1432,17 @@ void AdvanceRX()
|
|||
u16 framelen = *(u16*)&RXBuffer[8];
|
||||
if ((RXCount + ndata) > framelen)
|
||||
ndata = framelen - RXCount;
|
||||
printf("advance RX: addr=%05X, num=%d\n", IOPORT(W_RXTXAddr)<<1, ndata);
|
||||
|
||||
u16 addr = IOPORT(W_RXTXAddr) << 1;
|
||||
for (u32 i = 0; i < ndata; i++)
|
||||
{
|
||||
if (addr == (IOPORT(W_RXBufReadCursor) << 1))
|
||||
{
|
||||
// TODO!!!
|
||||
printf("!!! RX BUFFER FULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
*(u16*)&RAM[addr] = *(u16*)&RXBuffer[RXBufferPtr];
|
||||
|
||||
IncrementRXAddr(addr);
|
||||
|
@ -1266,7 +1454,7 @@ printf("advance RX: addr=%05X, num=%d\n", IOPORT(W_RXTXAddr)<<1, ndata);
|
|||
}
|
||||
|
||||
void FinishRX(u32 param)
|
||||
{
|
||||
{printf("finish RX\n");
|
||||
AdvanceRX();
|
||||
|
||||
u16 addr = IOPORT(W_RXTXAddr) << 1;
|
||||
|
@ -1283,8 +1471,7 @@ void FinishRX(u32 param)
|
|||
IOPORT(W_RXBufWriteCursor) = (addr & ~0x3) >> 1;
|
||||
|
||||
SetIRQ(0);
|
||||
SetStatus(1);
|
||||
printf("fnish RX\n");
|
||||
|
||||
WIFI_LOG("wifi: finished receiving packet %04X\n", *(u16*)&RXBuffer[12]);
|
||||
|
||||
ComStatus &= ~0x1;
|
||||
|
@ -1323,10 +1510,7 @@ printf("fnish RX\n");
|
|||
USCounter = timestamp;
|
||||
}
|
||||
|
||||
if ((!ComStatus) && (IOPORT(W_PowerState) & 0x0300))
|
||||
{
|
||||
SetStatus(9);
|
||||
}
|
||||
TRX_Next();
|
||||
}
|
||||
|
||||
void MPClientReplyRX(int client)
|
||||
|
@ -1661,12 +1845,12 @@ printf("checkRX: got frame\n");
|
|||
|
||||
void MPClientSync(u32 param)
|
||||
{
|
||||
if (!(ComStatus & 0x1))
|
||||
if (!ComStatus)
|
||||
{
|
||||
CheckRX(2);
|
||||
}
|
||||
else
|
||||
printf("MP CLIENT SYNC BUT ALREADY RECEIVING SHIT??\n");
|
||||
printf("MP CLIENT SYNC BUT ALREADY TRXING SHIT??\n");
|
||||
}
|
||||
|
||||
void PeriodicRXCheck(u32 time)
|
||||
|
@ -1675,7 +1859,7 @@ void PeriodicRXCheck(u32 time)
|
|||
|
||||
if ((!IsMPClient) || (USTimestamp > NextSync))
|
||||
{
|
||||
if (!(ComStatus & 0x1))
|
||||
if (!ComStatus)
|
||||
{
|
||||
CheckRX(0);
|
||||
}
|
||||
|
@ -2298,7 +2482,11 @@ void Write(u32 addr, u16 val)
|
|||
}
|
||||
return;
|
||||
case W_USCompareCnt:
|
||||
if (val & 0x0002) SetIRQ14(2);
|
||||
if (val & 0x0002)
|
||||
{
|
||||
UpdateTimers();
|
||||
SetIRQ14(2);
|
||||
}
|
||||
val &= 0x0001;
|
||||
break;
|
||||
case W_CmdCountCnt:
|
||||
|
|
Loading…
Reference in New Issue