⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 enc28j60的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:

/******************************************************************************
 *
 * Copyright:
 *    (C) 2000 - 2006 Embedded Artists AB
 *
 * Description:
 *    Sample application that implements ICMP (Ping) functionality.
 *
 *****************************************************************************/

/******************************************************************************
 * Includes
 *****************************************************************************/

#include "general.h"
#include "ethapi.h"

#include <ea_init.h>
#include <printf_P.h>
#include <string.h>
#include <lpc2xxx.h>


/******************************************************************************
 * Defines
 *****************************************************************************/
#define INBUF_LEN 1500

#define ARP_REQUEST    1         /* Operation ARP request      */
#define ARP_REPLY      2         /* Operation ARP reply        */

#define CRYSTAL_FREQUENCY FOSC
#define PLL_FACTOR        PLL_MUL
#define VPBDIV_FACTOR     PBSD

#define SPI_SLAVE_CS 0x00002000  //pin P0.13
#define ENC_RESET    0x00001000  //pin P0.12
#define FAILSAFE_VALUE 5000


/******************************************************************************
 * Local variables
 *****************************************************************************/

/*
 * The IP address assigned to the local host. 
 */ 
static tU8 localIP[4] = {192,168,1,230};

/*
 * The Ethernet address (MAC) assigned to the local host
 */
static tU8 mac[6] = {0x60, 0x06, 0x98, 0x01, 0x16, 0x34};
static tU8 inBuf[INBUF_LEN];
static tU8 bank = 0;

tU8 encReadReg(tU8 regNo);


/*****************************************************************************
 *
 * Description:
 *    Delay execution by a specified number of milliseconds by using
 *    timer #1. A polled implementation.
 *
 * Params:
 *    [in] delayInMs - the number of milliseconds to delay.
 *
 ****************************************************************************/
static void
delayMs(tU16 delayInMs)
{
  /*
   * setup timer #1 for delay
   */
  TIMER1_TCR = 0x02;          //stop and reset timer
  TIMER1_PR  = 0x00;          //set prescaler to zero
  TIMER1_MR0 = delayInMs * ((CRYSTAL_FREQUENCY * PLL_FACTOR)/ (1000 * VPBDIV_FACTOR));
  TIMER1_IR  = 0xff;          //reset all interrrupt flags
  TIMER1_MCR = 0x04;          //stop timer on match
  TIMER1_TCR = 0x01;          //start timer
  
  //wait until delay time has elapsed
  while (TIMER1_TCR & 0x01)
    ;
}

/*****************************************************************************
 *
 * Description:
 *    Sends and received one byte over the SPI serial channel.
 *    A polled implementation.
 *
 * Params:
 *    [in] byte - the byte to send.
 *
 * Return:
 *    The received byte.
 *
 ****************************************************************************/
static tU8
sendSpi(tU8 byte)
{
    tU32 failsafe;
    tU8  receivedByte;
    
  SPI_SPDR = byte;
  failsafe = 0;
  while(((SPI_SPSR & 0x80) == 0) && (failsafe < FAILSAFE_VALUE))
    failsafe++;

  receivedByte = SPI_SPDR;

  //reinitialize SPI if timeout
  if (failsafe >= FAILSAFE_VALUE)
  {
    printf("\nSPI-error: SSEL signal must be high!\n");
    receivedByte = 0x00;
    SPI_SPCCR = 0x08;    
    SPI_SPCR  = 0x20;  //no irq, MSB first, master, cpol=0, cpha=0
  }
  
  return receivedByte;
}

/*****************************************************************************
 *
 * Description:
 *    Low-level routine to write a register in ENC28J60
 *
 ****************************************************************************/
void
encWriteReg(tU8 regNo, tU8 data)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x40 | regNo);  //write in regNo
  sendSpi(data);
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
  
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x1f);          //read reg 0x1f

  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to read a register in ENC28J60
 *
 ****************************************************************************/
tU8
encReadReg(tU8 regNo)
{
  tU8 rxByte;

  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x1f);          //read reg 0x1f

  bank = sendSpi(0) & 0x3;
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP


  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(regNo);         //read reg i
  rxByte = sendSpi(0);

  //check if MAC or MII register
  if (((bank == 2) && (regNo <= 0x1a)) ||
      ((bank == 3) && (regNo <= 0x05 || regNo == 0x0a)))
    //ignore first byte and read another byte
{
    rxByte = sendSpi(0);
printf("\nRead MAC or MII reg = %x value=%x", regNo, rxByte);
}  
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP

  return rxByte;
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to read a received frame in the ENC28J60
 *
 ****************************************************************************/
void
encReadBuff(tU16 length, tU8 *pBuff)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x20 | 0x1a);   //read buffer memory

  while(length--)
  {
    if(pBuff != NULL)
      *pBuff++ = sendSpi(0);
    else
      sendSpi(0);
  }

  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to write a frame to be transmitted in the ENC28J60
 *
 ****************************************************************************/
void
encWriteBuff(tU16 length, tU8 *pBuff)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x60 | 0x1a);   //write buffer memory

  while(length--)
    sendSpi(*pBuff++);

  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to set a bit in one register in the ENC28J60
 *
 ****************************************************************************/
void
encBitSet(tU8 regNo, tU8 data)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0x80 | regNo);  //bit field set 
  sendSpi(data);
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to clear a bit in one register in the ENC28J60
 *
 ****************************************************************************/
void
encBitClr(tU8 regNo, tU8 data)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0xA0 | regNo);  //bit field clear 
  sendSpi(data);
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Low-level routine to reset the ENC28J60
 *
 ****************************************************************************/
void
encReset(void)
{
  IOCLR0 = SPI_SLAVE_CS;  //activate SPI
  sendSpi(0xff);          //soft reset
  IOSET0 = SPI_SLAVE_CS;  //deactivate SP
}


/*****************************************************************************
 *
 * Description:
 *    Initialize the SPI channle #0
 *
 ****************************************************************************/
void
initSpi(void)
{
  //connect SPI bus to IO-pins
  PINSEL0 |= 0x00005500;
  
  //initialize SPI interface
  SPI_SPCCR = 0x08;    
  SPI_SPCR  = 0x20;  //no irq, MSB first, master, cpol=0, cpha=0

  //make SPI slave chip select an output and set signal high
  IODIR |= SPI_SLAVE_CS;
  IOSET  = SPI_SLAVE_CS;

  //reset ENC28J60
  IODIR |= ENC_RESET;
  IOSET  = ENC_RESET;
  IOCLR  = ENC_RESET;
  delayMs(1);              //reset pulse width > 2 us
  IOSET  = ENC_RESET;
  delayMs(1);              //wait >300us after reset
}


/*****************************************************************************
 *
 * Description:
 *    Checksum calculation. 16-bit one's complement. 
 *
 * Params:
 *    [in] pStartAddress - pointer to beginning of data 
 *    [in] len           - length of data 
 *    [in] initialValue  - precalculated checksum (e.g. pseudo header) 
 *
 * Returns:
 *    calculated checksum 
 *
 ****************************************************************************/
static tU16
checksum(tU8* pStartAddress,
         tU16 len,
         tU16 initialValue)
{
  tU32 csum       = ~initialValue & 0x0000ffff;
  tU8 *p8bit      = NULL;
  tU16 val16      = 0;

  tU32 aWordCount = len / 2;
  p8bit           = pStartAddress;

  while (aWordCount-- > 0)
  {
    val16  = *p8bit++;
    val16 |= *p8bit << 8;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -