void Enc28j60::reset(void) { // Trigger a software reset writeOperation(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); // Errata #2: Wait for at least 1 ms after software reset for (uint32_t i = 0x1FFF; i != 0; i--) ; // Wait until the clock becomes ready while(!readOperation(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY); // Store a pointer to the next packet nextPacketPtr = RXSTART_INIT; // Set the packet transmit and receive buffers writeRegister(ERXST, RXSTART_INIT); writeRegister(ERXRDPT, RXSTART_INIT); writeRegister(ERXND, RXSTOP_INIT); writeRegister(ETXST, TXSTART_INIT); writeRegister(ETXND, TXSTOP_INIT); // Set MACON1 register writeRegisterByte(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS); // Set MACON2 register writeRegisterByte(MACON2, 0x00); // Set MACON3 registers writeOperation(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN); // Set Non-Back-to-Back Inter-Packet Gap writeRegister(MAIPG, 0x0C12); // Set Back-to-Back Inter-Packet Gap writeRegisterByte(MABBIPG, 0x12); // Set maximum frame length writeRegister(MAMXFL, MAX_FRAMELEN); // Set MAC address writeRegisterByte(MAADR5, macAddress[0]); writeRegisterByte(MAADR4, macAddress[1]); writeRegisterByte(MAADR3, macAddress[2]); writeRegisterByte(MAADR2, macAddress[3]); writeRegisterByte(MAADR1, macAddress[4]); writeRegisterByte(MAADR0, macAddress[5]); // Errata #9/10: Disable loopback in half-duplex writePhy(PHCON2, PHCON2_HDLDIS); // Set ECON1 bank setBank(ECON1); // Enable packet interrupt writeOperation(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE); // Enable packet reception writeOperation(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); }
/* ======================================================================= */ ENC28J60Driver::ENC28J60Driver(uint8_t* macaddr, uint8_t csPin): EthernetDriver(macaddr){ this->sendBuffer = new ENC28J60Buffer(this,TXSTART_INIT+1, TXSTOP_INIT, MAX_FRAMELEN, 0,false); this->recvBuffer = new ENC28J60Buffer(this,RXSTART_INIT, RXSTOP_INIT, MAX_FRAMELEN, 0,true); this->stashBuffer = new ENC28J60Buffer(this,STASH_START_INIT, STASH_STOP_INIT, STASH_STOP_INIT - STASH_START_INIT +1, 0,false); if (bitRead(SPCR, SPE) == 0) initSPI(); selectPin = csPin; pinMode(selectPin, OUTPUT); disableChip(); writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); delay(2); // errata B7/2 while (!readOp(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY) ; gNextPacketPtr = RXSTART_INIT; writeReg(ERXST, RXSTART_INIT); writeReg(ERXRDPT, RXSTART_INIT); writeReg(ERXND, RXSTOP_INIT); writeReg(ETXST, TXSTART_INIT); writeReg(ETXND, TXSTOP_INIT); writeRegByte(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN); writeReg(EPMM0, 0x303f); writeReg(EPMCS, 0xf7f9); writeRegByte(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); writeRegByte(MACON2, 0x00); writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); writeReg(MAIPG, 0x0C12); writeRegByte(MABBIPG, 0x12); writeReg(MAMXFL, MAX_FRAMELEN); writeRegByte(MAADR5, macaddr[0]); writeRegByte(MAADR4, macaddr[1]); writeRegByte(MAADR3, macaddr[2]); writeRegByte(MAADR2, macaddr[3]); writeRegByte(MAADR1, macaddr[4]); writeRegByte(MAADR0, macaddr[5]); writePhy(PHCON2, PHCON2_HDLDIS); SetBank(ECON1); writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); this->revision = readRegByte(EREVID); // microchip forgot to step the number on the silcon when they // released the revision B7. 6 is now rev B7. We still have // to see what they do when they release B8. At the moment // there is no B8 out yet if (this->revision > 5) this->revision++; }