예제 #1
0
void enc28j60PowerDown() 
{
  enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
  while(enc28j60Read(ESTAT) & ESTAT_RXBUSY);
  while(enc28j60Read(ECON1) & ECON1_TXRTS);
  enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
}
예제 #2
0
/******************************************************************************
 * Function:        void MACMemCopyAsync(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopyTo(FLOW flow, unsigned int destAddr, unsigned int len)
{
    unsigned int sourceAddr = RXSTART_INIT;
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
        if ((CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) <= RXSTOP_INIT)
        {
            sourceAddr = CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE;
        }
        else
        {
            unsigned int rest = (CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) - RXSTOP_INIT;
            sourceAddr = rest - 1;
        }
    }
    else if (flow == TX)
    {
	sourceAddr = TXSTART_INIT;
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    // Need compensate circular buffer WHEN RX COPY !!!
    unsigned int floatingEnd = (sourceAddr + len);
    if (flow == RX)
    {	
	if (floatingEnd >= RXSTOP_INIT)
	{
	    // Adjusting END for DMA copy
	    // otherwise it will never reach end pointer
	    // and never get it done
	    unsigned int tempEnd = (floatingEnd - RXSTOP_INIT);
	    if (tempEnd > 0) tempEnd--;
	    
	    floatingEnd = tempEnd;
	}
    }
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low(floatingEnd));
    enc28j60Write(EDMANDH, high(floatingEnd));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
}
예제 #3
0
/******************************************************************************
 * Function:        void MACSendTx(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Send Tx buffer
 *
 * Note:            None
 *****************************************************************************/
void MACSendTx(void)
{
    // clear TXIF and config transmit interrupt if the case
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
    
    // send the contents of the transmit buffer onto the network
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
    
    
}
예제 #4
0
/******************************************************************************
 * Function:        void MACMemCopyAsync(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopyFrom(FLOW flow, unsigned int sourceAddr, unsigned int len)
{
    unsigned int destAddr = TXSTART_INIT;
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
	destAddr = NextPacketLocation.Val;
    }
    else if (flow == TX)
    {
	destAddr = TXSTART_INIT + 1;
        
        // write per-packet control byte (0x00 means use macon3 settings)
        enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low((sourceAddr + len))); // + RXD_STATUS_VECTOR_SIZE));
    enc28j60Write(EDMANDH, high((sourceAddr + len))); // + RXD_STATUS_VECTOR_SIZE));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
    
    if (flow == TX)
    {
        // Set the write pointer to start of transmit buffer area
        enc28j60Write(EWRPTL, low((destAddr - 1)));
        enc28j60Write(EWRPTH, high((destAddr - 1)));
        
        // Set the TXND pointer to correspond to the packet size given
        enc28j60Write(ETXNDL, low(((destAddr - 1) + len)));
        enc28j60Write(ETXNDH, high(((destAddr - 1) + len)));
    }
    
}
예제 #5
0
void enc28j60SetBank(uint8_t address)
{
    if ((address & BANK_MASK) != Enc28j60Bank) {
        enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);
        Enc28j60Bank = address & BANK_MASK;
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);
    }
예제 #6
0
/******************************************************************************
 * Function:        void MACSendSystemReset(void)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        MACSendSystemReset sends the System Reset SPI command to
 *                  the Ethernet controller.  It resets all register contents
 *                  (except for ECOCON) and returns the device to the power
 *                  on default state.
 *
 * Note:            None
 *****************************************************************************/
void MACSendSystemReset(void)
{
    // perform system reset
    enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
    delay(50);
        
}//end MACSendSystemReset
예제 #7
0
/******************************************************************************
 * Function:        void MACEnableRecv(void)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          None
 *
 * Side Effects:    none
 *
 * Overview:        Enable ENC28J60 hardware receiving status
 *
 * Note:            None
 *****************************************************************************/
void MACEnableRecv(void)
{
    // 5.
    
    // enable interrutps
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
    // enable packet reception
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
}
예제 #8
0
파일: enc28j60.c 프로젝트: schugabe/FWS
void enc28j60SetBank(uint8_t address)
{
        // set the bank (if needed)
        if((address & BANK_MASK) != Enc28j60Bank)
        {
                // set the bank
                enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
                enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
                Enc28j60Bank = (address & BANK_MASK);
        }
예제 #9
0
/******************************************************************************
 * Function:        void MACDiscardRx(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Marks the last received packet (obtained using
 *                  MACGetHeader())as being processed and frees the buffer
 *                  memory associated with it
 *
 * Note:            Is is safe to call this function multiple times between
 *                  MACGetHeader() calls.  Extra packets won't be thrown away
 *                  until MACGetHeader() makes it available.
 *****************************************************************************/
void MACDiscardRx(void)
{
    // Update Current pointer
    CurrentPacketLocation.Val = NextPacketLocation.Val;
    
    enc28j60Write(ERXRDPTL, NextPacketLocation.Byte.LB);
    enc28j60Write(ERXRDPTH, NextPacketLocation.Byte.HB);

    // decrement the packet counter indicate we are done with this packet
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
}
예제 #10
0
// Set register bank
static void enc28j60SetBank(uint8_t address)
{
  uint8_t tmp;
  tmp = (address & BANK_MASK);
  
  if(tmp != Enc28j60Bank) // set the bank (if needed)
  {
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, tmp>>5);
    Enc28j60Bank = tmp;
  }
예제 #11
0
/******************************************************************************
 * Function:        void MACWriteTXBufferOffset(unsigned char* _buf, unsigned int _size, unsigned int offset_len)
 *
 * PreCondition:    none
 *
 * Input:           *_buf: buffer to write data 
 *                  _size: amount data to write
 *                  offset:memory pointer to write data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Writes bytes to TX Buffer space and skips offset
 *
 * Note:            None
 *****************************************************************************/
void MACWriteTXBufferOffset(unsigned char* _buf, unsigned int _size, unsigned int offset_len)
{
    // calc offset
    unsigned int offsetStart  = TXSTART_INIT + offset_len;
    unsigned int offsetEnd    = offsetStart + _size; 
    
    // Set the write pointer to start of transmit buffer area
    enc28j60Write(EWRPTL, low(offsetStart));
    enc28j60Write(EWRPTH, high(offsetStart));
    
    // Set the TXND pointer to correspond to the packet size given
    enc28j60Write(ETXNDL, low(offsetEnd));
    enc28j60Write(ETXNDH, high(offsetEnd));
    
    // write per-packet control byte (0x00 means use macon3 settings)
    enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
    
    // copy the packet into the transmit buffer
    enc28j60WriteBuffer(_size, _buf);
}
예제 #12
0
/******************************************************************************
 * Function:        void MACInit(void)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          None
 *
 * Side Effects:    none
 *
 * Overview:        Init. ENC28J60 hardware
 *
 * Note:            None
 *****************************************************************************/
void MACInit(void)
{
    // 1.
    
    NextPacketLocation.Val = 0;
    CurrentPacketLocation.Val = 0;
    
    // RESET the entire ENC28J60, clearing all registers
    MACSendSystemReset();
    
    // Start up in Bank 0 and configure the receive buffer boundary pointers
    // and the buffer write protect pointer (receive buffer read pointer)
    NextPacketLocation.Val = RXSTART_INIT;
    CurrentPacketLocation.Val = RXSTART_INIT;

    enc28j60Write(ERXSTL, low(RXSTART_INIT));
    enc28j60Write(ERXSTH, high(RXSTART_INIT));
    enc28j60Write(ERXRDPTL, low(RXSTART_INIT));    // Write low byte first
    enc28j60Write(ERXRDPTH, high(RXSTART_INIT));   // Write high byte last
    enc28j60Write(ERXNDL, low(RXSTOP_INIT));
    enc28j60Write(ERXNDH, high(RXSTOP_INIT));
    enc28j60Write(ETXSTL, low(TXSTART_INIT));
    enc28j60Write(ETXSTH, high(TXSTART_INIT));

    // Enter Bank 1 and configure Receive Filters
    // For broadcast packets we allow only ARP packtets
    // All other packets should be unicast only for our mac (MAADR)
    //
    // The pattern to match on is therefore
    // Type     ETH.DST
    // ARP      BROADCAST
    // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
    // in binary these poitions are:11 0000 0011 1111
    // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
    enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
    enc28j60Write(EPMM0, 0x3F);
    enc28j60Write(EPMM1, 0x30);
    enc28j60Write(EPMCSL, 0xF9);
    enc28j60Write(EPMCSH, 0xF7);    
    // promiscuous mode
    //enc28j60Write(ERXFCON, ERXFCON_CRCEN);
    
    // Disable the CLKOUT output to reduce EMI generation
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x00);   // Output off (0V)
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x01); // 25.000MHz
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECOCON, 0x03); // 8.3333MHz (*4 with PLL is 33.3333MHz)
    
    // Enable the receive portion of the MAC
    // full duplex
    //enc28j60Write(MACON1, (MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS));
    // half duplex
    enc28j60Write(MACON1, MACON1_MARXEN);
    
    // bring MAC out of reset
    enc28j60Write(MACON2, 0x00);
    
    // Pad packets to 60 bytes, add CRC, and check Type/Length field.
    // full duplex
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3,
    //                MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
    // half duplex
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3,
                   MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
    
    // Allow infinite deferals if the medium is continuously busy
    // (do not time out a transmission if the half duplex medium is
    // completely saturated with other people's data)
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON4, MACON4_DEFER);
    // Clear because we are in full duplex mode
    //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, MACON4, MACON4_DEFER);
    
    // Set the maximum packet size which the controller will accept
    unsigned int limit = 1518;  // 6+6+2+1500+4
                                // 1518 is the IEEE 802.3 specified limit
    enc28j60Write(MAMXFLL, low(limit));  
    enc28j60Write(MAMXFLH, high(limit));
    
    // set inter-frame gap (back-to-back)
    // half duplex
    enc28j60Write(MABBIPG, 0x12);
    // full duplex
    //enc28j60Write(MABBIPG, 0x15);
    
    // set inter-frame gap (non-back-to-back)
    enc28j60Write(MAIPGL, 0x12);
    // half duplex
    enc28j60Write(MAIPGH, 0x00);
    // full duplex
    //enc28j60Write(MAIPGH, 0x0C);

    // Late collisions occur beyond 63+8 bytes (8 bytes for preamble/start of frame delimiter)
    // 55 is all that is needed for IEEE 802.3, but ENC28J60 B5 errata for improper link pulse
    // collisions will occur less often with a larger number.
    enc28j60Write(MACLCON2, 63);
    
}
예제 #13
0
void enc28j60PowerUp() 
{
  enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
  while(!enc28j60Read(ESTAT) & ESTAT_CLKRDY);
}
예제 #14
0
/******************************************************************************
 * Function:        void DMACopy(FLOW flow, unsigned int destAddr, unsigned int len)
 *
 * PreCondition:    SPI bus must be initialized (done in MACInit()).
 *
 * Input:           destAddr:   Destination address in the Ethernet memory to
 *                              copy to.  If (PTR_BASE)-1 is specified, the 
 *								current EWRPT value will be used instead.
 *                  sourceAddr: Source address to read from.  If (PTR_BASE)-1 is
 *                              specified, the current ERDPT value will be used
 *                              instead.
 *                  len:        Number of bytes to copy
 *
 * Output:          None
 *
 * Side Effects:    Moves read and write pointers. DMA conflict with transmitting and receiving
 *
 * Overview:        Bytes are asynchrnously transfered within the buffer.  Call
 *                  MACIsMemCopyDone() to see when the transfer is complete.
 *
 * Note:            If a prior transfer is already in progress prior to
 *                  calling this function, this function will block until it
 *                  can start this transfer.
 *
 *                  If (PTR_BASE)-1 is used for the sourceAddr or destAddr
 *                  parameters, then that pointer will get updated with the
 *                  next address after the read or write.
 *****************************************************************************/
void DMACopy(FLOW flow, unsigned int destAddr, unsigned int len)
{
    // finally using tx socket space, after 2 years developing this enc28's EEPROM approach
    // for documentation sake, I have made following organization
    // to enc28's 8k eeprom
    // 0H ~ 800H (2K) - RX FIFO (CYCLIC)
    // 802H ~ 1000H (2K-1byte) - TX FIFO (FLAT)
    // 1002H ~ 1401H - Socket RX Bank 0 (FLAT)
    // 1402H ~ 1801H - Socket RX Bank 1 (not used yet) (FLAT)
    // 1803H ~ 1C02H - Socket TX Bank 0 (FLAT)
    // 1C03H ~ 1FFEH - Socket TX Bank 1 (not used yet) (FLAT) -- Total 8K EEPROM used ONLY by this library!
    // Errata 7b has lots of issues about this addresses
    // I have made them by the book!
    // By Renato Aloi (May 2015)
    // While trying to remmember all rules to implement last and most important option: Write at TX Socket Buffer!
    unsigned int sourceAddr = RXSTART_INIT; // RX Copy From FIFO To Bank
    
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_DMAST);
    
    // Defining source address by read or write pointer
    if (flow == RX)
    {
        if ((CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) <= RXSTOP_INIT)
        {
            sourceAddr = CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE;
        }
        else
        {
            unsigned int rest = (CurrentPacketLocation.Val + RXD_STATUS_VECTOR_SIZE) - RXSTOP_INIT;
            sourceAddr = rest - 1;
        }
    }
    else if (flow == TX)
    {
	sourceAddr = SOCKET_TX_START(0); // TX Copy From Bank To FIFO
    }
    
    // Source Init Address
    enc28j60Write(EDMASTL, low(sourceAddr));
    enc28j60Write(EDMASTH, high(sourceAddr));
    
    // Source Stop Address
    // Need compensate circular buffer WHEN RX COPY !!!
    unsigned int floatingEnd = (sourceAddr + len);
    if (flow == RX)
    {	
	if (floatingEnd >= RXSTOP_INIT)
	{
	    // Adjusting END for DMA copy
	    // otherwise it will never reach end pointer
	    // and never get it done
	    unsigned int tempEnd = (floatingEnd - RXSTOP_INIT);
	    if (tempEnd > 0) tempEnd--;
	    
	    floatingEnd = tempEnd;
	}
    }
    
    // Source Stop Address
    enc28j60Write(EDMANDL, low(floatingEnd));
    enc28j60Write(EDMANDH, high(floatingEnd));
    
    // Destination Init Address
    enc28j60Write(EDMADSTL, low(destAddr));
    enc28j60Write(EDMADSTH, high(destAddr));
    
    // Clear flag
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
    
    // Execute!
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
}