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

📄 eth97j60.c

📁 单片机c语言程序设计100例--基于PIC+PROTEUS
💻 C
📖 第 1 页 / 共 4 页
字号:
/*********************************************************************
 *
 *     MAC Module (Microchip PIC18F97J60 family) for Microchip TCP/IP Stack
 *
 *********************************************************************
 * FileName:        ETH97J60.c
 * Dependencies:    ETH97J60.h
 *					MAC.h
 *					string.h
 *                  StackTsk.h
 *                  Helpers.h
 *					Delay.h
 * Processor:       PIC18F97J60 family device
 * Complier:        MCC18 v3.02 or higher
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * This software is owned by Microchip Technology Inc. ("Microchip") 
 * and is supplied to you for use exclusively as described in the 
 * associated software agreement.  This software is protected by 
 * software and other intellectual property laws.  Any use in 
 * violation of the software license may subject the user to criminal 
 * sanctions as well as civil liability.  Copyright 2006 Microchip
 * Technology Inc.  All rights reserved.
 *
 * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL 
 * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED 
 * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 
 * INFRINGEMENT.  Microchip shall in no event be liable for special, 
 * incidental, or consequential damages.
 *
 * Author               Date   	 Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Rawin Rojvanit       07/26/05 Stuff
 * Howard Schlunder     11/17/05 Ported to PIC18F97J60
 * Howard Schlunder		06/16/06 Synchronized with ENC28J60 code
********************************************************************/
#define THIS_IS_MAC_LAYER

#include <string.h>
#include "..\Include\StackTsk.h"
#include "..\Include\Helpers.h"
#include "..\Include\Delay.h"
#include "..\Include\MAC.h"

#if !defined(__18F97J60) && !defined(__18F96J65) && !defined(__18F96J60) && !defined(__18F87J60) && !defined(__18F86J65) && !defined(__18F86J60) && !defined(__18F67J60) && !defined(__18F66J65) && !defined(__18F66J60) && !defined(HI_TECH_C)
	#error "ETH97J60.c MAC layer for PIC18F97J60 family Ethernet modules is included, but a PIC18F97J60 family mirocontroller is not selected.  Did you mean to include the ENC28J60.c MAC layer instead?  Is your target processor selected correctly?"
#endif

#if defined(STACK_USE_SLIP)
#error Unexpected module is detected.
#error This file must be linked when SLIP module is not in use.
#endif


/** D E F I N I T I O N S ****************************************************/
// Since the Ethernet PHY doesn't support auto-negotiation, full-duplex mode is 
// not compatible with most switches/routers.  If a dedicated network is used 
// where the duplex of the remote node can be manually configured, you may 
// change this configuration.  Otherwise, half duplex should always be used.
#define HALF_DUPLEX
//#define FULL_DUPLEX

// Pseudo Functions
#define LOW(a) 					(a & 0xFF)
#define HIGH(a) 				((a>>8) & 0xFF)

// NIC RAM definitions
#define RAMSIZE	8192ul		
#define TXSTART (RAMSIZE-(MAC_TX_BUFFER_COUNT * (MAC_TX_BUFFER_SIZE + 8ul)))
#define RXSTART	(0ul)						// Should be an even memory address
#define	RXSTOP	((TXSTART-2ul) | 0x0001ul)	// Odd for errata workaround
#define RXSIZE	(RXSTOP-RXSTART+1ul)

#define ETHER_IP	(0x00u)
#define ETHER_ARP	(0x06u)

#define MAXFRAMEC	(1500u+sizeof(ETHER_HEADER)+4u)

// A generic structure representing the Ethernet header starting all Ethernet 
// frames
typedef struct _ETHER_HEADER
{
    MAC_ADDR        DestMACAddr;
    MAC_ADDR        SourceMACAddr;
    WORD_VAL        Type;
} ETHER_HEADER;

// A header appended at the start of all RX frames by the hardware
typedef struct _ENC_PREAMBLE
{
    WORD			NextPacketPointer;
    RXSTATUS		StatusVector;

    MAC_ADDR        DestMACAddr;
    MAC_ADDR        SourceMACAddr;
    WORD_VAL        Type;
} ENC_PREAMBLE;

typedef struct _DATA_BUFFER
{
	WORD_VAL StartAddress;
	WORD_VAL EndAddress;
	struct 
	{
		unsigned char bFree : 1;
		unsigned char bTransmitted : 1;
	} Flags;
} DATA_BUFFER;



// Internal and externally used MAC level variables.
#if MAC_TX_BUFFER_COUNT > 1
static DATA_BUFFER TxBuffers[MAC_TX_BUFFER_COUNT];
#endif
BUFFER CurrentTxBuffer;
BUFFER LastTXedBuffer;

// Internal MAC level variables and flags.
WORD_VAL NextPacketLocation;
WORD_VAL CurrentPacketLocation;
BOOL WasDiscarded;

// Temp fix for bank f issue where registers are not located properly on PIC18F97J60 silicon revision A1 (A1 is beta silicon only)
// This can can be deleted for all production silicon chips (Rev. B0)
#pragma udata eth_sfr0=0xEFC
union
{
	volatile far unsigned char EIRx;
	volatile far struct {
	  unsigned RXERIF:1;
	  unsigned TXERIF:1;
	  unsigned WOLIF:1;
	  unsigned TXIF:1;
	  unsigned LINKIF:1;
	  unsigned DMAIF:1;
	  unsigned PKTIF:1;
	} EIRxbits;
} EIRUnion;
#pragma udata eth_sfr1=0xEFA
volatile far unsigned char EDATAx;
#pragma udata eth_sfr3=0xEE0
union {
	volatile far unsigned int ERDPTx;
	volatile far struct {
		unsigned char ERDPTLx;
		unsigned char ERDPTHx;
	} ERDPTxbytes;
} ERDPTUnion;
#pragma udata eth_sfr4=0xEDF
union {
	volatile far unsigned char       ECON1x;
	volatile far struct {
	  unsigned :2;
	  unsigned RXEN:1;
	  unsigned TXRTS:1;
	  unsigned CSUMEN:1;
	  unsigned DMAST:1;
	  unsigned RXRST:1;
	  unsigned TXRST:1;
	} ECON1xbits;
}ECON1Union;
//#pragma udata eth_sfr5=0xEFD
//volatile far unsigned char ESTATx;
#pragma udata

#define	EDATA		EDATAx
#define EIR			EIRUnion.EIRx
#define EIRbits		EIRUnion.EIRxbits
#define ERDPT		ERDPTUnion.ERDPTx
#define ERDPTH		ERDPTUnion.ERDPTxbytes.ERDPTHx
#define ERDPTL		ERDPTUnion.ERDPTxbytes.ERDPTLx
#define ECON1		ECON1Union.ECON1x
#define ECON1bits	ECON1Union.ECON1xbits
#define ESTAT		ESTATx


/******************************************************************************
 * Function:        void MACInit(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        MACInit enables the Ethernet module, waits for the 
 *                  to become ready, and programs all registers for future 
 *                  TX/RX operations.
 *
 * Note:            This function blocks for at least 1ms, waiting for the 
 *                  hardware to stabilize.
 *****************************************************************************/
void MACInit(void)
{
	BYTE i;
	
	
    LATAbits.LATA0 = 0;
    LATAbits.LATA1 = 0;
    TRISAbits.TRISA0 = 0;   // Set LED0 as output
    TRISAbits.TRISA1 = 0;   // Set LED1 as output
    ECON2bits.ETHEN = 1;    // Enable Ethernet!

	// Wait for PHYRDY to become set.
    while(!ESTATbits.PHYRDY);

    // Wait at least 1ms for everything to stabilize
    DelayMs(1);

#if MAC_TX_BUFFER_COUNT > 1
    // On Init, all transmit buffers are free.
    for (i = 0; i < MAC_TX_BUFFER_COUNT; i++ )
    {
        TxBuffers[i].StartAddress.Val = TXSTART + ((WORD)i * (MAC_TX_BUFFER_SIZE+8));
        TxBuffers[i].Flags.bFree = TRUE;
    }
#endif
    CurrentTxBuffer = 0;
	
	// Configure the receive buffer boundary pointers 
	// and the buffer write protect pointer (receive buffer read pointer)
	WasDiscarded = TRUE;
	NextPacketLocation.Val = RXSTART;

	ERXST = RXSTART;
	ERXRDPTL = LOW(RXSTOP);	// Write low byte first
	ERXRDPTH = HIGH(RXSTOP);// Write high byte last
#if RXSTOP != 0x1FFF	// The RESET default ERXND is 0x1FFF
	ERXND = RXSTOP;
#endif
#if TXSTART != 0		// The RESET default ETXST is 0
	ETXST = TXSTART;
#endif

	// Configure Receive Filters 
	// (No need to reconfigure - Unicast OR Broadcast with CRC checking is 
	// acceptable)
	//ERXFCON = ERXFCON_CRCEN;     // Promiscious mode


	// Configure the MAC
	// Enable the receive portion of the MAC
    MACON1 = MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN; Nop();

	// Pad packets to 60 bytes, add CRC, and check Type/Length field.
    MACON3 = MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN; Nop();

    // 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)
    MACON4 = MACON4_DEFER; Nop();

	// Late collisions occur beyond 63 bytes (default for 802.3 spec)
    MACLCON2 = 63; Nop();
	
	// Set non-back-to-back inter-packet gap to 9.6us.  The back-to-back 
	// inter-packet gap (MABBIPG) is set by MACSetDuplex() which is called 
	// later.
    MAIPGL = 0x12; Nop();
    MAIPGH = 0x0C; Nop();

	// Set the maximum packet size which the controller will accept
    MAMXFLL = LOW(MAXFRAMEC); Nop();
    MAMXFLH = HIGH(MAXFRAMEC); Nop();
	

    // Initialize physical MAC address registers
    MAADR1 = AppConfig.MyMACAddr.v[0]; Nop();
    MAADR2 = AppConfig.MyMACAddr.v[1]; Nop();
    MAADR3 = AppConfig.MyMACAddr.v[2]; Nop();
    MAADR4 = AppConfig.MyMACAddr.v[3]; Nop();
    MAADR5 = AppConfig.MyMACAddr.v[4]; Nop();
    MAADR6 = AppConfig.MyMACAddr.v[5]; Nop();

	// Disable half duplex loopback in PHY.  
	WritePHYReg(PHCON2, PHCON2_HDLDIS);

	// Configure LEDA to display LINK status, LEDB to display TX/RX activity
	SetLEDConfig(0x0472);
	
	// Use the external LEDB polarity to determine weather full or half duplex 
	// communication mode should be set.  
#if defined(FULL_DUPLEX)
	MACSetDuplex(FULL);		// Function exits with Bank 2 selected
#else
	MACSetDuplex(HALF);		// Function exits with Bank 2 selected
#endif

	// Enable packet reception
    ECON1bits.RXEN = 1;
}//end MACInit


/******************************************************************************
 * Function:        BOOL MACIsLinked(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          TRUE: If the PHY reports that a link partner is present 
 *						  and the link has been up continuously since the last 
 *						  call to MACIsLinked()
 *					FALSE: If the PHY reports no link partner, or the link went 
 *						   down momentarily since the last call to MACIsLinked()
 *
 * Side Effects:    None
 *
 * Overview:        Returns the PHSTAT1.LLSTAT bit.
 *
 * Note:            None
 *****************************************************************************/
BOOL MACIsLinked(void)
{
	// LLSTAT is a latching low link status bit.  Therefore, if the link 
	// goes down and comes back up before a higher level stack program calls
	// MACIsLinked(), MACIsLinked() will still return FALSE.  The next 
	// call to MACIsLinked() will return TRUE (unless the link goes down 
	// again).
	return ReadPHYReg(PHSTAT1).PHSTAT1bits.LLSTAT;
}


/******************************************************************************
 * Function:        BOOL MACIsTxReady(BOOL HighPriority)
 *
 * PreCondition:    None
 *
 * Input:           HighPriority: TRUE: Check the hardware ECON1.TXRTS bit
 *								  FALSE: Check if a TX buffer is free
 *
 * Output:          TRUE: If no Ethernet transmission is in progress
 *					FALSE: If a previous transmission was started, and it has 
 *						   not completed yet.  While FALSE, the data in the 
 *						   transmit buffer and the TXST/TXND pointers must not
 *						   be changed.
 *
 * Side Effects:    None
 *
 * Overview:        Returns the ECON1.TXRTS bit
 *
 * Note:            None
 *****************************************************************************/
BOOL MACIsTxReady(BOOL HighPriority)
{
#if MAC_TX_BUFFER_COUNT > 1
	BUFFER i;

	if(HighPriority)
#endif
	{
	    return !ECON1bits.TXRTS;
	}

#if MAC_TX_BUFFER_COUNT > 1

	// Check if the current buffer can be modified.  It cannot be modified if 
	// the TX hardware is currently transmitting it.
	if(CurrentTxBuffer == LastTXedBuffer)
	{
	    return !ECON1bits.TXRTS;
	}

	// Check if a buffer is available for a new packet
	for(i = 1; i < MAC_TX_BUFFER_COUNT; i++)
	{

⌨️ 快捷键说明

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