private void RXInitialize() { var tmp = (uint)Cosmos.Core.Memory.Heap.Alloc(32 * 16 + 16); RXDescs = (tmp % 16 != 0) ? (tmp + 16 - (tmp % 16)) : tmp; for (uint i = 0; i < 32; i++) { RXDesc *desc = (RXDesc *)(RXDescs + (i * 16)); desc->addr = (uint)Cosmos.Core.Memory.Heap.Alloc(2048 + 16); desc->status = 0; } WriteRegister(REG_RXDESCLO, RXDescs); WriteRegister(REG_RXDESCHI, 0); WriteRegister(REG_RXDESCLEN, 32 * 16); WriteRegister(REG_RXDESCHEAD, 0); WriteRegister(REG_RXDESCTAIL, 32 - 1); WriteRegister(REG_RCTRL, (1 << 1) | // Receiver Enable (1 << 2) | // Store Bad Packets (1 << 3) | // Unicast Promiscuous Enabled (1 << 4) | // Multicast Promiscuous Enabled (0 << 6) | // No Loopback (0 << 8) | // Free Buffer Threshold is 1/2 of RDLEN (1 << 15) | // Broadcast Accept Mode (1 << 26) | // Strip Ethernet CRC (0 << 16) //Buffer size of 2048 bytes ); }
private void HandleIRQ(ref INTs.IRQContext aContext) { uint Status = ReadRegister(0xC0); if ((Status & 0x04) != 0) { //Turn link up LinkUp(); } if ((Status & 0x10) != 0) { //Good threshold } if ((Status & 0x80) != 0) { uint _RXCurr = RXCurr; RXDesc *desc = (RXDesc *)(RXDescs + (RXCurr * 16)); while ((desc->status & 0x1) != 0) { byte[] data = new byte[desc->length]; byte * ptr = (byte *)desc->addr; for (int i = 0; i < desc->length; i++) { data[i] = ptr[i]; } DataReceived(data); desc->status = 0; RXCurr = (RXCurr + 1) % 32; WriteRegister(0x2818, _RXCurr); } } }