diff options
| -rw-r--r-- | src/Wifi.cpp | 150 | 
1 files changed, 104 insertions, 46 deletions
| diff --git a/src/Wifi.cpp b/src/Wifi.cpp index db4ad42..4ce016c 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -58,13 +58,16 @@ typedef struct      u8 Rate;      u8 CurPhase;      u32 CurPhaseTime; +    u32 HalfwordTimeMask;  } TXSlot;  TXSlot TXSlots[6];  u8 RXBuffer[2048]; +u32 RXBufferPtr;  u32 RXTime; +u32 RXHalfwordTimeMask;  u16 RXEndAddr;  u32 ComStatus; // 0=waiting for packets  1=receiving  2=sending @@ -465,7 +468,12 @@ bool ProcessTX(TXSlot* slot, int num)      slot->CurPhaseTime--;      if (slot->CurPhaseTime > 0)      { -        if (slot->CurPhase == 2) +        if (slot->CurPhase == 1) +        { +            if (!(slot->CurPhaseTime & slot->HalfwordTimeMask)) +                IOPORT(W_RXTXAddr)++; +        } +        else if (slot->CurPhase == 2)          {              MPReplyTimer--;              if (MPReplyTimer == 0 && MPNumReplies > 0) @@ -513,8 +521,16 @@ bool ProcessTX(TXSlot* slot, int num)                  SetStatus(3);              u32 len = slot->Length; -            if (slot->Rate == 2) len *= 4; -            else                 len *= 8; +            if (slot->Rate == 2) +            { +                len *= 4; +                slot->HalfwordTimeMask = 0x7; +            } +            else +            { +                len *= 8; +                slot->HalfwordTimeMask = 0xF; +            }              slot->CurPhase = 1;              slot->CurPhaseTime = len; @@ -522,6 +538,10 @@ bool ProcessTX(TXSlot* slot, int num)              *(u16*)&RAM[slot->Addr + 0xC + 22] = IOPORT(W_TXSeqNo) << 4;              IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF; +            // set TX addr +            // TODO: what does this say when sending a MP ack?? I don't think that packet is stored in RAM +            IOPORT(W_RXTXAddr) = slot->Addr >> 1; +              int txlen = Platform::MP_SendPacket(&RAM[slot->Addr], 12 + slot->Length);              if (num != 4) printf("wifi: sent %d/%d bytes of slot%d packet, framectl=%04X, %04X %04X\n",                                   txlen, slot->Length+12, num, *(u16*)&RAM[slot->Addr + 0xC], *(u16*)&RAM[slot->Addr + 0x24], *(u16*)&RAM[slot->Addr + 0x26]); @@ -632,6 +652,25 @@ bool ProcessTX(TXSlot* slot, int num)  } +inline void IncrementRXAddr(u16& addr, u16 inc) +{ +    addr += inc; +    if (addr >= (IOPORT(W_RXBufEnd) & 0x1FFE)) +    { +        addr -= (IOPORT(W_RXBufEnd) & 0x1FFE); +        addr += (IOPORT(W_RXBufBegin) & 0x1FFE); +    } +} + +inline void IncrementRXAddr(u16& addr) +{ +    addr += 2; +    if (addr == (IOPORT(W_RXBufEnd) & 0x1FFE)) +    { +        addr = (IOPORT(W_RXBufBegin) & 0x1FFE); +    } +} +  bool CheckRX(bool block)  {      if (!(IOPORT(W_RXCnt) & 0x8000)) @@ -725,44 +764,33 @@ bool CheckRX(bool block)          printf("wifi: received packet FC:%04X SN:%04X CL:%04X\n", framectl, *(u16*)&RXBuffer[12+4+6+6+6], *(u16*)&RXBuffer[12+4+6+6+6+2+2]);      // make RX header -    // TODO: make it upon RX end      if (bssidmatch) rxflags |= 0x8000;      *(u16*)&RXBuffer[0] = rxflags;      *(u16*)&RXBuffer[2] = 0x0040; // ??? -    *(u16*)&RXBuffer[4] = 0x7777;      *(u16*)&RXBuffer[6] = txrate;      *(u16*)&RXBuffer[8] = framelen;      *(u16*)&RXBuffer[10] = 0x4080; // min/max RSSI. dunno -    RXTime = framelen * ((txrate==0x14) ? 4:8); +    RXTime = framelen; -    // TODO: write packet progressively? -    // TODO: RX/TX addr register -    framelen += 12; -    u16 addr = IOPORT(W_RXBufWriteCursor) << 1; -    for (int i = 0; i < framelen; i += 2) +    if (txrate == 0x14)      { -        *(u16*)&RAM[addr] = *(u16*)&RXBuffer[i]; -        addr += 2; - -        if (addr == (IOPORT(W_RXBufEnd) & 0x1FFE)) -            addr = (IOPORT(W_RXBufBegin) & 0x1FFE); - -        if (addr == (IOPORT(W_RXBufReadCursor) << 1)) -        { -            printf("wifi: RX buffer full\n"); -            // TODO: proper error management -            return false; -        } +        RXTime *= 4; +        RXHalfwordTimeMask = 0x7; +    } +    else +    { +        RXTime *= 8; +        RXHalfwordTimeMask = 0xF;      } -    if (addr & 0x2) addr += 2; -    if (addr == (IOPORT(W_RXBufEnd) & 0x1FFE)) -        addr = (IOPORT(W_RXBufBegin) & 0x1FFE); +    u16 addr = IOPORT(W_RXBufWriteCursor) << 1; +    IncrementRXAddr(addr, 12); +    IOPORT(W_RXTXAddr) = addr >> 1; -    RXEndAddr = (addr & ~0x3) >> 1; +    RXBufferPtr = 12;      SetIRQ(6);      SetStatus(6); @@ -877,29 +905,64 @@ void USTimer(u32 param)      {          // TODO: make sure it isn't possible to send and receive at the same time          RXTime--; -        if (RXTime == 0) +        if (!(RXTime & RXHalfwordTimeMask))          { -            IOPORT(W_RXBufWriteCursor) = RXEndAddr; -            SetIRQ(0); -            SetStatus(1); +            u16 addr = IOPORT(W_RXTXAddr) << 1; +            *(u16*)&RAM[addr] = *(u16*)&RXBuffer[RXBufferPtr]; + +            IncrementRXAddr(addr); +            RXBufferPtr += 2; -            if (TXCurSlot == -1) +            if (RXTime == 0) // finished receiving              { -                ComStatus = 0; -                RXCounter = 0; +                if (addr & 0x2) IncrementRXAddr(addr); + +                // copy the RX header +                u16 headeraddr = IOPORT(W_RXBufWriteCursor) << 1; +                *(u16*)&RAM[headeraddr] = *(u16*)&RXBuffer[0]; IncrementRXAddr(headeraddr); +                *(u16*)&RAM[headeraddr] = *(u16*)&RXBuffer[2]; IncrementRXAddr(headeraddr, 4); +                *(u16*)&RAM[headeraddr] = *(u16*)&RXBuffer[6]; IncrementRXAddr(headeraddr); +                *(u16*)&RAM[headeraddr] = *(u16*)&RXBuffer[8]; IncrementRXAddr(headeraddr); +                *(u16*)&RAM[headeraddr] = *(u16*)&RXBuffer[10]; + +                IOPORT(W_RXBufWriteCursor) = (addr & ~0x3) >> 1; + +                SetIRQ(0); +                SetStatus(1); + +                if (TXCurSlot == -1) +                { +                    ComStatus = 0; +                    RXCounter = 0; +                } + +                if ((RXBuffer[0] & 0x0F) == 0x0C) +                { +                    u16 clientmask = *(u16*)&RXBuffer[0xC + 26]; +                    if (IOPORT(W_AIDLow) && (RXBuffer[0xC + 4] & 0x01) && (clientmask & (1 << IOPORT(W_AIDLow)))) +                    { +                        printf("MP: attempting to reply: %04X %04X, delay=%04X\n", +                               IOPORT(W_TXSlotReply1), IOPORT(W_TXSlotReply2), *(u16*)&RXBuffer[0xC + 24]); + +                        SendMPReply(*(u16*)&RXBuffer[0xC + 24], *(u16*)&RXBuffer[0xC + 26]); +                    } +                }              } -            if ((RXBuffer[0] & 0x0F) == 0x0C) +            if (addr == (IOPORT(W_RXBufReadCursor) << 1))              { -                u16 clientmask = *(u16*)&RXBuffer[0xC + 26]; -                if (IOPORT(W_AIDLow) && (RXBuffer[0xC + 4] & 0x01) && (clientmask & (1 << IOPORT(W_AIDLow)))) +                printf("wifi: RX buffer full\n"); +                RXTime = 0; +                SetStatus(1); +                if (TXCurSlot == -1)                  { -                    printf("MP: attempting to reply: %04X %04X, delay=%04X\n", -                           IOPORT(W_TXSlotReply1), IOPORT(W_TXSlotReply2), *(u16*)&RXBuffer[0xC + 24]); - -                    SendMPReply(*(u16*)&RXBuffer[0xC + 24], *(u16*)&RXBuffer[0xC + 26]); +                    ComStatus = 0; +                    RXCounter = 0;                  } +                // TODO: proper error management              } + +            IOPORT(W_RXTXAddr) = addr >> 1;          }      } @@ -1029,11 +1092,6 @@ u16 Read(u32 addr)      case W_TXBusy:          return IOPORT(W_TXBusy) & 0x001F; // no bit for MP replies. odd - -        //case 0x214: NDS::debug(0); break; -        //case 0x040: NDS::debug(0); break; -        //case 0x54: printf("wifi: read WRCSR -> %04X\n", IOPORT(0x54)); break; -        case 0x268: printf("read RXTXADDR\n"); break;      }      //printf("WIFI: read %08X\n", addr); |