示例#1
0
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++;
}