i have made the porting few weeks ago but i have no tested it because i have no hardware at this time so i will be very happy if you test an debug it
Code: Select all
{
*****************************************************************************
* Name : ETH97J60.BAS *
* Date : 03/04/2008 *
* Version : 1.0 - Based around Microchip TCP/IP stack version 4.18 *
* Notes : *
* ========================================================================= *
* Medium Access Control (MAC) Layer for Microchip PIC18F97J60 family *
* Module for Microchip TCP/IP Stack *
* -Provides access to PIC18F97J60 family Ethernet controller *
* -Reference: PIC18F97J60 Family data sheet, IEEE 802.3 Standard *
* *
*****************************************************************************
* Software License Agreement *
* *
* Copyright © 2002-2007 Microchip Technology Inc. All rights *
* reserved. *
* *
* Microchip licenses to you the right to use, modify, copy, and *
* distribute: *
* (i) the Software when embedded on a Microchip microcontroller or *
* digital signal controller product (“Device”) which is *
* integrated into Licensee’s product or *
* (ii) ONLY the Software driver source files ENC28J60.c and *
* ENC28J60.h ported to a non-Microchip device used in *
* conjunction with a Microchip ethernet controller for the *
* sole purpose of interfacing with the ethernet controller. *
* *
* You should refer to the license agreement accompanying this *
* Software for additional information regarding your rights and *
* obligations. *
* *
* THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT *
* WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL *
* MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR *
* CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF *
* PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS *
* BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE *
* THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER *
* SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT *
* (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. *
*****************************************************************************
/(*********************** 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.}
Module ETH97J60
Include "NETConfig.bas"
Include "NETTypes.bas"
Include "NETUtils.bas"
Include "system.bas"
#define HALF_DUPLEX
//#define FULL_DUPLEX
// Rest are Receive Buffers
Public Const
MAC_IP = ($00),
MAC_ARP = ($06),
MAC_UNKNOWN = ($FF)
Const
ETHER_IP = ($00),
ETHER_ARP = ($06)
// A generic structure representing the Ethernet header starting all Ethernet
// frames
Public Structure MAC_ETHER_HEADER
DestMACAddr As MAC_ADDR
SourceMACAddr As MAC_ADDR
_Type As WORD_VAL
End Structure
// TXSTATUS bits...
Structure TXBits
v(7) As Byte
ByteCount As v(0).AsWord // 16
_CollisionCount As v(2) // 4
CRCError As v(2).4 // 1
LengthCheckError As v(2).5 // 1
LengthOutOfRange As v(2).6 // 1
Done As v(2).7 // 1
Multicast As v(3).0 // 1
Broadcast As v(3).1 // 1
PacketDefer As v(3).2 // 1
ExcessiveDefer As v(3).3 // 1
MaximumCollisions As v(3).4 // 1
LateCollision As v(3).5 // 1
Giant As v(3).6 // 1
Underrun As v(3).7 // 1
BytesTransmittedOnWire As v(4).AsWord // 16
ControlFrame As v(6).0 // 1
PauseControlFrame As v(6).1 // 1
BackpressureApplied As v(6).2 // 1
VLANTaggedFrame As v(6).3 // 1
// 4 zeros
End Structure
// TXSTATUS...
Structure TXStatus
v(7) As Byte
Bits As TXBits Union
End Structure
// RXSTATUS bits...
Structure RXBits
v(4) As Byte
ByteCount As v(0).AsWord // 16
PreviouslyIgnored As v(2).0 // 1
RXDCPreviouslySeen As v(2).1 // 1
CarrierPreviouslySeen As v(2).2 // 1
CodeViolation As v(2).3 // 1
CRCError As v(2).4 // 1
LengthCheckError As v(2).5 // 1
LengthOutOfRange As v(2).6 // 1
ReceiveOk As v(2).Booleans(7) // 1
Multicast As v(3).0 // 1
Broadcast As v(3).1 // 1
DribbleNibble As v(3).2 // 1
ControlFrame As v(3).3 // 1
PauseControlFrame As v(3).4 // 1
UnsupportedOpcode As v(3).5 // 1
VLANType As v(3).6 // 1
zero As v(3).7 // 1 zero
End Structure
// RXSTATUS
Structure RXSTATUS
v(4) As Byte
Bits As RXBits Union
End Structure
// A header appended at the start of all RX frames by the hardware
Structure ENC_PREAMBLE
NextPacketPointer As Word
StatusVector As RXSTATUS
DestMACAddr As MAC_ADDR
SourceMACAddr As MAC_ADDR
_Type As WORD_VAL
End Structure
// Internal MAC level variables and flags.
Dim
NextPacketLocation As WORD_VAL,
CurrentPacketLocation As WORD_VAL,
WasDiscarded As Boolean,
wTXWatchdog As Word,
TxRequestToSend As ECON1.booleans(3),
PHYClockIsReady As ESTAT.booleans(0),
BUSY As MISTAT.booleans(0),
DMAST As ECON1.booleans(5)
Public Const
MAC_TX_BUFFER_SIZE = _MAC_TX_BUFFER_SIZE,
RAMSIZE = _RAMSIZE,
TXSTART = _TXSTART,
RXSTART = _RXSTART,
RXSTOP = _RXSTOP,
RXSIZE = _RXSIZE,
BASE_TX_ADDR = _BASE_TX_ADDR,
BASE_TCB_ADDR = _BASE_TCB_ADDR,
BASE_HTTPB_ADDR = _BASE_HTTPB_ADDR
Structure TPHCON1
Val As Word
PDPXMD As Val.8
PPWRSV As Val.11
PLOOPBK As Val.14
PRST As Val.15
End Structure
Structure TPHSTAT1
Val As Word
JBSTAT As Val.1
LLSTAT As Val.Booleans(2)
PHDPX As Val.11
PFDPX As Val.12
End Structure
Structure TPHID2
Val As Word
PREV0 As Val.0
PREV1 As Val.1
PREV2 As Val.2
PREV3 As Val.3
PPN0 As Val.4
PPN1 As Val.5
PPN2 As Val.6
PPN3 As Val.7
PPN4 As Val.8
PPN5 As Val.9
PID19 As Val.10
PID20 As Val.11
PID21 As Val.12
PID22 As Val.13
PID23 As Val.14
PID24 As Val.15
// alt
PREV As Val // 0..3 (bits 4)
PPNL As Val // 4..7 (bits 4)
PPNH As Val.Byte1 // 8..9 (bits 2)
PID As Val.Byte1 // 10..15 (bits 6)
End Structure
Structure TPHCON2
Val As Word
HDLDIS As Val.8
JABBER As Val.10
TXDIS As Val.13
FRCLNK As Val.14
End Structure
Structure TPHSTAT2
Val As Word
PLRITY As Val.5
DPXSTAT As Val.9
LSTAT As Val.10
COLSTAT As Val.11
RXSTAT As Val.12
TXSTAT As Val.13
End Structure
Structure TPHIE
Val As Word
PGEIE As Val.1
PLNKIE As Val.4
End Structure
Structure TPHIR
Val As Word
PGIF As Val.2
PLNKIF As Val.4
End Structure
Structure TPHLCON
Val As Word
STRCH As Val.1
LFRQ0 As Val.2
LFRQ1 As Val.3
LBCFG0 As Val.4
LBCFG1 As Val.5
LBCFG2 As Val.6
LBCFG3 As Val.7
LACFG0 As Val.8
LACFG1 As Val.9
LACFG2 As Val.10
LACFG3 As Val.11
// alt...
LFRQ As Val // 2..3 (bits 2)
LBCFG As Val // 4..7 (bits 4)
LACFG As Val.Byte1 // 8..11 (bits 4)
End Structure
Public Structure PHYREG
Val As WORD_VAL
PHCON1bits As TPHCON1 Union
PHSTAT1bits As TPHSTAT1 Union
PHID2bits As TPHID2 Union
PHCON2bits As TPHCON2 Union
PHSTAT2bits As TPHSTAT2 Union
PHIEbits As TPHIE Union
PHIRbits As TPHIR Union
PHLCONbits As TPHLCON Union
End Structure
// PH Register Locations
Public Const
PHCON1 = $00,
PHSTAT1 = $01,
PHID1 = $02,
PHID2 = $03,
PHCON2 = $10,
PHSTAT2 = $11,
PHIE = $12,
PHIR = $13,
PHLCON = $14
{*******************************************************************************
* Individual Register Bits
********************************************************************************}
Const
// ETH/MAC/MII bits
// EIE bits ----------
EIE_PKTIE = (1<<6),
EIE_DMAIE = (1<<5),
EIE_LINKIE = (1<<4),
EIE_TXIE = (1<<3),
EIE_TXERIE = (1<<1),
EIE_RXERIE = (1),
// EIR bits ----------
EIR_PKTIF = (1<<6),
EIR_DMAIF = (1<<5),
EIR_LINKIF = (1<<4),
EIR_TXIF = (1<<3),
EIR_TXERIF = (1<<1),
EIR_RXERIF = (1),
// ESTAT bits ---------
ESTAT_BUFER = (1<<6),
ESTAT_RXBUSY = (1<<2),
ESTAT_TXABRT = (1<<1),
ESTAT_PHYRDY = (1),
// ECON2 bits --------
ECON2_AUTOINC = (1<<7),
ECON2_PKTDEC = (1<<6),
ECON2_ETHEN = (1<<5),
// ECON1 bits --------
ECON1_TXRST = (1<<7),
ECON1_RXRST = (1<<6),
ECON1_DMAST = (1<<5),
ECON1_CSUMEN = (1<<4),
ECON1_TXRTS = (1<<3),
ECON1_RXEN = (1<<2),
// ERXFCON bits ------
ERXFCON_UCEN = (1<<7),
ERXFCON_ANDOR = (1<<6),
ERXFCON_CRCEN = (1<<5),
ERXFCON_PMEN = (1<<4),
ERXFCON_MPEN = (1<<3),
ERXFCON_HTEN = (1<<2),
ERXFCON_MCEN = (1<<1),
ERXFCON_BCEN = (1),
// MACON1 bits --------
MACON1_TXPAUS = (1<<3),
MACON1_RXPAUS = (1<<2),
MACON1_PASSALL =(1<<1),
MACON1_MARXEN = (1),
// MACON3 bits --------
MACON3_PADCFG2 = (1<<7),
MACON3_PADCFG1 = (1<<6),
MACON3_PADCFG0 = (1<<5),
MACON3_TXCRCEN = (1<<4),
MACON3_PHDREN = (1<<3),
MACON3_HFRMEN = (1<<2),
MACON3_FRMLNEN = (1<<1),
MACON3_FULDPX = (1),
// MACON4 bits --------
MACON4_DEFER = (1<<6),
// MICMD bits ---------
MICMD_MIISCAN = (1<<1),
MICMD_MIIRD = (1),
// MISTAT bits --------
MISTAT_NVALID = (1<<2),
MISTAT_SCAN = (1<<1),
MISTAT_BUSY = (1),
// EFLOCON bits -----
EFLOCON_FCEN1 = (1<<1),
EFLOCON_FCEN0 = (1),
// PHY bits
// PHCON1 bits ----------
PHCON1_PDPXMD As Word = (1<<8),
// PHSTAT1 bits --------
PHSTAT1_LLSTAT As Word = (1<<2),
// PHCON2 bits ----------
PHCON2_FRCLNK As Word = (1<<14),
PHCON2_HDLDIS As Word = (1<<8),
PHCON2_RXAPDIS As Word = (1<<4),
// PHSTAT2 bits --------
PHSTAT2_TXSTAT As Word = (1<<13),
PHSTAT2_RXSTAT As Word = (1<<12),
PHSTAT2_COLSTAT As Word = (1<<11),
PHSTAT2_LSTAT As Word = (1<<10),
// PHIE bits -----------
PHIE_PLNKIE As Word = (1<<4),
PHIE_PGEIE As Word = (1<<1),
// PHIR bits -----------
PHIR_PLNKIF As Word = (1<<4),
PHIR_PGIF As Word = (1<<2),
// PHLCON bits -------
PHLCON_LACFG3 As Word = (1<<11),
PHLCON_LACFG2 As Word = (1<<10),
PHLCON_LACFG1 As Word = (1<<9),
PHLCON_LACFG0 As Word = (1<<8),
PHLCON_LBCFG3 As Word = (1<<7),
PHLCON_LBCFG2 As Word = (1<<6),
PHLCON_LBCFG1 As Word = (1<<5),
PHLCON_LBCFG0 As Word = (1<<4),
PHLCON_LFRQ1 As Word = (1<<3),
PHLCON_LFRQ0 As Word = (1<<2),
PHLCON_STRCH As Word = (1<<1)
(******************************************************************************
* Function: MACPut(Byte Val)
*
* PreCondition: EWRPT must point To the location To begin writing.
*
* Input: Byte To Write into the Ethernet buffer memory
*
* Output: None
*
* Side Effects: None
*
* Overview: Writes To the EDATA Register, which will indirectly
* increment EWRPTH:EWRPTL.
*
* Note: None
*****************************************************************************)
Public Sub MACPut(Val As Byte)
// Note: Due to a PIC18F97J60 bug, you must use the MOVFF instruction to
// write to EDATA or else the read pointer (ERDPT) will inadvertently
// increment.
PRODL = Val
ASM
movff PRODL, EDATA
End ASM
End Sub
(******************************************************************************
* Function: Byte MACGet()
*
* PreCondition: ERDPT must point To the place To Read from.
*
* Input: None
*
* Output: Byte Read from the Ethernet's buffer RAM
*
* Side Effects: None
*
* Overview: MACGet returns the Byte pointed To by ERDPT And
* increments ERDPT so MACGet() can be called again. The
* increment will follo the receive buffer wrapping boundary.
*
* Note: For better performance, implement this Function As a macro:
* #define MACGet() (EDATA)
*****************************************************************************)
Public Function MACGet() As EDATA
// result = EDATA
End Function
//end MACGet
(******************************************************************************
* Function: Word MACGetArray(Byte *Val, Word len)
*
* PreCondition: ERDPT must point To the place To Read from.
*
* Input: *Val: Pointer To storage location
* len: Number of Bytes To Read from the data buffer.
*
* Output: Byte(s) of data Read from the data buffer.
*
* Side Effects: None
*
* Overview: Reads several sequential Bytes from the data buffer
* And places them into local memory. ERDPT is incremented
* after each Byte, folloing the same rules As MACGet().
*
* Note: None
*****************************************************************************)
Public Function MACGetArray(Val As Word, Len As Word) As Word
Dim i As Word
Dim Dummy As Byte
Dec(Val)
// Read the data
While i < Len
Inc(i)
If Val <> 0 Then
Inc(Val)
FSR0 = Val
INDF0 = EDATA
Else
Dummy = EDATA
EndIf
Wend
result = i
End Function
(******************************************************************************
* Function: MACPutArray(Byte *Val, Word len)
*
* PreCondition: EWRPT must point To the location To begin writing.
*
* Input: *Val: Pointer To source of Bytes To copy.
* len: Number of Bytes To Write To the data buffer.
*
* Output: None
*
* Side Effects: None
*
* Overview: MACPutArray writes several sequential Bytes To the
* Ethernet buffer RAM. It performs faster than multiple MACPut()
* calls. EWRPT is incremented by len.
*
* Note: None
*****************************************************************************)
Public Sub MACPutArray(Val As Word, Len As Word)
// Note: Due to a PIC18F97J60 bug, you must use the MOVFF instruction to
// write to EDATA or else the read pointer (ERDPT) will inadvertently
// increment.
While Len <> 0
FSR0 = Val
PRODL = INDF0 // Start sending the byte
ASM
movff PRODL, EDATA
End ASM
Inc(Val)
Dec(Len)
Wend
End Sub
(******************************************************************************
* Function: ReadPHYReg
*
* PreCondition: Ethernet Module must be enabled (ECON1.ETHEN = 1).
*
* Input: Address of the PHY Register To Read from.
*
* Output: 16 Bits of data Read from the PHY Register.
*
* Side Effects: None
*
* Overview: ReadPHYReg performs an MII Read operation. While in
* progress, it simply polls the MII BUSY Bit wasting time
* (10.24us).
*
* Note: None
*****************************************************************************)
Function ReadPHYReg(Register As Byte) As PHYREG
Dim Res As PHYREG
// Set the right address and start the register read operation
MIREGADR = Register Nop()
MICMD = MICMD_MIIRD Nop()
// Loop to wait until the PHY register has been read through the MII
// This requires 10.24us
While BUSY
Wend
// Stop reading
MICMD = $00 Nop()
// Obtain results and return
Res.Val.v(0) = MIRDL
Nop()
Res.Val.v(1) = MIRDH
Result = Res
End Function
{******************************************************************************
* Function: WritePHYReg
*
* PreCondition: Ethernet Module must be enabled (ECON1.ETHEN = 1).
*
* Input: Address of the PHY Register To write To.
* 16 Bits of data To write To PHY Register.
*
* Output: None
*
* Side Effects: None
*
* Overview: WritePHYReg performs an MII write operation. While in
* progress, it simply polls the MII BUSY Bit wasting time
* (10.24us).
*
* Note: None
*****************************************************************************}
Sub WritePHYReg( Register As Byte, Data As Word)
// Write the data through the MIIM interface
// Order is important: write lo byte first, hi byte last
//
// Due to a silicon problem, you cannot access any register with LSb address
// bits of $16 between your write to MIWRL and MIWRH or else the value in
// MIWRL will be corrupted. This inline assembly prevents this by copying
// the value to PRODH:PRODL first, which is at fixed locations of
// $FF4:$FF3. These addresses have LSb address bits of $14 and $13.
// Interrupts must be disabled to prevent arbitrary ISR code from accessing
// memory with LSb bits of $16 and corrupting the MIWRL value.
Dim GIESave As Byte
GIESave = INTCON And $C0 // Save GIEH and GIEL bits
INTCON = INTCON And $3F // Clear INTCONbits.GIEH and INTCONbits.GIEL
MIREGADR = register // Address to MIREGADR
PRODL = data.Byte0
PRODH = data.Byte1
MIWRL = PRODL // Lo byte to MIWRL
MIWRH = PRODH // Hi byte to MIWRH
INTCON = INTCON Or GIESave // Restore GIEH and GIEL value
// Wait until the PHY register has been written
// This operation requires 10.24us
While BUSY Wend
End Sub
(*
******************************************************************************
* Macro: void SetLEDConfig(Word NewConfig)
* PreCondition: SPI bus must be initialized (done in MACInit()).
* Input: NewConfig - xxx0: Pulse stretching disabled
* xxx2: Pulse stretch To 40ms (default)
* xxx6: Pulse stretch To 73ms
* xxxA: Pulse stretch To 139ms
*
* xx1x: LEDB - TX
* xx2x: LEDB - RX (default)
* xx3x: LEDB - collisions
* xx4x: LEDB - link
* xx5x: LEDB - duplex
* xx7x: LEDB - TX And RX
* xx8x: LEDB - on
* xx9x: LEDB - off
* xxAx: LEDB - blink fast
* xxBx: LEDB - blink slow
* xxCx: LEDB - link And RX
* xxDx: LEDB - link And TX And RX
* xxEx: LEDB - duplex And collisions
*
* x1xx: LEDA - TX
* x2xx: LEDA - RX
* x3xx: LEDA - collisions
* x4xx: LEDA - link (default)
* x5xx: LEDA - duplex
* x7xx: LEDA - TX And RX
* x8xx: LEDA - on
* x9xx: LEDA - off
* xAxx: LEDA - blink fast
* xBxx: LEDA - blink slow
* xCxx: LEDA - link And RX
* xDxx: LEDA - link And TX And RX
* xExx: LEDA - duplex And collisions
* Output: None
* Side Effects: None
* Overview: Writes the value of NewConfig into the PHLCON PHY register.
* The LED pins will beginning outputting the new
* configuration immediately.
* Note:
*****************************************************************************/
*)
Public Sub SetLEDConfig(NewConfig As Word)
WritePHYReg(PHLCON, NewConfig)
End Sub
{******************************************************************************
* Function: MACInit()
*
* 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.
*****************************************************************************}
Public Sub MACInit()
//Dim i As Byte
LATA.0 = 0
LATA.1 = 0
TRISA.0 = 0 // Set LED0 as output
TRISA.1 = 0 // Set LED1 as output
FSR2 = AddressOf(ECON2)
INDF2.5 = 1 // Enable Ethernet!
// FSR2 = AddressOf(ESTAT)
While Not PHYClockIsReady Wend//INDF2.0 <> 1 Wend // Wait for PHYRDY to become set.
DelayMS(1)
// Configure the receive buffer boundary pointers
// and the buffer write protect pointer (receive buffer read pointer)
WasDiscarded = TRUE
NextPacketLocation.Val = RXSTART
FSR2 = AddressOf(ERXSTL)
POSTINC2 = Lo(RXSTART)
INDF2 = Hi(RXSTART)
FSR2 = AddressOf(ERXRDPTL)
POSTINC2 = Lo(RXSTOP) // Write lo byte first
INDF2 = Hi(RXSTOP) // Write hi byte last
FSR2 = AddressOf(ERXNDL)
POSTINC2 = Lo(RXSTOP) // Write lo byte first
INDF2 = Hi(RXSTOP) // Write hi byte last
FSR2 = AddressOf(ETXSTL)
POSTINC2 = Lo(RXSTART)
INDF2 = Hi(RXSTART)
// Write a permanant per packet control byte of $00
FSR2 = AddressOf(EWRPTL)
POSTINC2 = Lo(RXSTART)
INDF2 = Hi(RXSTART)
MACPut($00)
// 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 Or MACON1_RXPAUS Or MACON1_MARXEN
Nop()
// Pad packets to 60 bytes, add CRC, and check Type/Length field.
#if defined(FULL_DUPLEX)
MACON3 = MACON3_PADCFG0 Or MACON3_TXCRCEN Or MACON3_FRMLNEN Or MACON3_FULDPX
Nop()
MABBIPG = $15
Nop()
#else
MACON3 = MACON3_PADCFG0 Or MACON3_TXCRCEN Or MACON3_FRMLNEN
Nop()
MABBIPG = $12
Nop()
#endif
// 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()
// 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 = $12
Nop()
MAIPGH = $0C
Nop()
// Set the maximum packet size which the controller will accept
MAMXFLL = Lo(6+6+2+1500+4)
Nop()
MAMXFLH = Hi(6+6+2+1500+4)
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 and set RXAPDIS bit as per errata
WritePHYReg(PHCON2, PHCON2_HDLDIS Or PHCON2_RXAPDIS)
// Configure LEDA to display LINK status, LEDB to display TX/RX activity
SetLEDConfig($3472)
// Set the PHY into the proper duplex state
#if defined(FULL_DUPLEX)
WritePHYReg(PHCON1, PHCON1_PDPXMD)
#else
WritePHYReg(PHCON1, $0000)
#endif
// Enable packet reception
ECON1.2 = 1
End Sub
//end MACInit
{******************************************************************************
* Function: BOOL MACIsLinked()
*
* 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
*****************************************************************************}
Public Function MACIsLinked() As Boolean
Dim PHYRegister As PHYREG
// 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).
PHYRegister = ReadPHYReg(PHSTAT1)
result = PHYRegister.PHSTAT1bits.LLSTAT
End Function
{******************************************************************************
* Function: BOOL MACIsTxReady()
*
* PreCondition: None
*
* Input: None
*
* 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.3 Bit
*
* Note: None
*****************************************************************************}
Public Function MACIsTxReady() As Boolean
result = Not TxRequestToSend //ECON1.3
End Function
{******************************************************************************
* Function: MACDiscardRx()
*
* 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.
*****************************************************************************}
Public Sub MACDiscardRx()
Dim NewRXRDLocation As WORD_VAL
// Make sure the current packet was not already discarded
If WasDiscarded Then
Exit
EndIf
WasDiscarded = true
// Decrement the next packet pointer before writing it into
// the ERXRDPT registers. This is a silicon errata workaround.
// RX buffer wrapping must be taken into account if the
// NextPacketLocation is precisely RXSTART.
NewRXRDLocation.Val = NextPacketLocation.Val - 1
If NewRXRDLocation.Val > RXSTOP Then
NewRXRDLocation.Val = RXSTOP
EndIf
// Decrement the RX packet counter register, EPKTCNT
ECON2.6 = 1
// Move the receive read pointer to unwrite-protect the memory used by the
// last packet. The writing order is important: set the lo byte first,
// hi byte last.
ERXRDPTL = NewRXRDLocation.v(0)
ERXRDPTH = NewRXRDLocation.v(1)
// The PKTIF flag should automatically be cleared by hardware, but
// early beta silicon requires that you manually clear it. This should be
// unneeded for production A0 silicon and later.
EIR.6 = 0
End Sub
(******************************************************************************
* Function: Word MACGetFreeRxSize()
*
* PreCondition: None
*
* Input: None
*
* Output: A Word estimate of how much RX buffer space is free at
* the present time.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************)
Public Function MACGetFreeRxSize() As Word
Dim ReadPT, WritePT As WORD_VAL
// Read the Ethernet hardware buffer write pointer. Because packets can be
// received at any time, it can change between reading the low and high
// bytes. A loop is necessary to make certain a proper low/high byte pair
// is read.
Repeat
// Save EPKTCNT in a temporary location
ReadPT.v(0) = EPKTCNT
WritePT.v(0) = ERXWRPTL
WritePT.v(1) = ERXWRPTH
Until EPKTCNT = ReadPT.v(0)
// Determine where the write protection pointer is
ReadPT.v(0) = ERXRDPTL
ReadPT.v(1) = ERXRDPTH
// Calculate the difference between the pointers, taking care to account
// for buffer wrapping conditions
If WritePT.Val > ReadPT.Val Then
result = (RXSTOP - RXSTART) - (WritePT.Val - ReadPT.Val)
ElseIf WritePT.Val = ReadPT.Val Then
result = RXSIZE - 1
Else
result = ReadPT.Val - WritePT.Val - 1
EndIf
End Function
(******************************************************************************
* Function: BOOL MACGetHeader(MAC_ADDR *remote, Byte* Type)
*
* PreCondition: None
*
* Input: *remote: Location To store the Source MAC address of the
* received frame.
* *Type: Location of a Byte To store the constant
* MAC_UNKNOWN, ETHER_IP, Or ETHER_ARP, representing
* the contents of the Ethernet Type field.
*
* Output: TRUE: If a packet was waiting in the RX buffer. The
* remote, And Type values are updated.
* FALSE: If a packet was Not pending. remote And Type are
* Not changed.
*
* Side Effects: Last packet is discarded If MACDiscardRx() hasn't already
* been called.
*
* Overview: None
*
* Note: None
*****************************************************************************)
Public Function MACGetHeader(ByRef remote As MAC_ADDR, ByRef _Type As Byte) As Boolean
Dim header As ENC_PREAMBLE
Dim PacketCount As Byte
// Test if at least one packet has been received and is waiting
FSR2 = AddressOf(EPKTCNT)
PacketCount = INDF2
If PacketCount = 0 Then
result = false
Exit
EndIf
// Make absolutely certain that any previous packet was discarded
If WasDiscarded = false Then
MACDiscardRx()
result = false
Exit
EndIf
// Set the read pointer to the beginning of the next unprocessed packet
FSR2 = AddressOf(ERDPTL)
CurrentPacketLocation.Val = NextPacketLocation.Val
POSTINC2 = CurrentPacketLocation.v(0)
INDF2 = CurrentPacketLocation.v(1)
// Obtain the MAC header from the Ethernet buffer
MACGetArray(@header, SizeOf(header))
// The EtherType field, like most items transmitted on the Ethernet medium
// are in big endian.
header._Type.Val = NETUtils.swaps(header._Type.Val)
// Do a sanity check. There might be a bug in code someplace if this
// Reset() ever happens. Check for potential errors in array/pointer writing code.
If header.NextPacketPointer > RXSTOP Or
header.NextPacketPointer.0 <> 0 Or
header.StatusVector.Bits.zero <> 0 Or
header.StatusVector.Bits.CRCError <> 0 Or
header.StatusVector.Bits.ByteCount > 1518 Or
Not header.StatusVector.Bits.ReceiveOk Then
Reset()
EndIf
// Save the location where the hardware will write the next packet to
NextPacketLocation.Val = header.NextPacketPointer
// Return the Ethernet frame's Source MAC address field to the caller
// This parameter is useful for replying to requests without requiring an
// ARP cycle.
// memcpy((void*)remote->v, (void*)header.SourceMACAddr.v, SizeOf( *remote));
remote.v = header.SourceMACAddr.v
// Return a simplified version of the EtherType field to the caller
_Type = MAC_UNKNOWN
If (header._Type.v(1) = $08) And (header._Type.v(0) = ETHER_IP Or header._Type.v(0) = ETHER_ARP) Then
_Type = header._Type.v(0)
EndIf
// Mark this packet as discardable
WasDiscarded = false
result = true
End Function
(******************************************************************************
* Function: MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen)
*
* PreCondition: MACIsTxReady() must return TRUE.
*
* Input: *remote: Pointer to memory which contains the destination
* MAC address (6 bytes)
* type: The constant ETHER_ARP or ETHER_IP, defining which
* value to write into the Ethernet header's type field.
* dataLen: Length of the Ethernet data payload
*
* Output: None
*
* Side Effects: None
*
* Overview: None
*
* Note: Because of the dataLen parameter, it is probably
* advantagous to call this function immediately before
* transmitting a packet rather than initially when the
* packet is first created. The order in which the packet
* is constructed (header first or data first) is not
* important.
*****************************************************************************)
Public Sub MACPutHeader(ByRef remote As MAC_ADDR, _Type As Byte, dataLen As Word)
FSR2 = AddressOf(EWRPTL)
POSTINC2 = Lo(TXSTART+1)
INDF2 = Hi(TXSTART+1)
// Calculate where to put the TXND pointer
dataLen = dataLen + SizeOf(MAC_ETHER_HEADER) + TXSTART
// Write the TXND pointer into the registers, given the dataLen given
FSR2 = AddressOf(ETXNDL)
POSTINC2 = dataLen.Byte0
INDF2 = dataLen.Byte0
// Set the per-packet control byte and write the Ethernet destination
// address
MACPutArray(@remote, SizeOf(MAC_ADDR))
// Write our MAC address in the Ethernet source field
MACPutArray(@AppConfig.MyMACAddr, SizeOf(AppConfig.MyMACAddr))
// Write the appropriate Ethernet Type WORD for the protocol being used
MACPut($08)
If _Type = MAC_IP Then
MACPut(ETHER_IP)
Else
MACPut(ETHER_ARP)
EndIf
End Sub
(******************************************************************************
* Function: MACFlush()
*
* PreCondition: A packet has been created by calling MACPut() And
* MACPutHeader().
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: MACFlush causes the current TX packet To be sent out on
* the Ethernet medium. The hardware MAC will take control
* And handle CRC generation, collision retransmission And
* other details.
*
* Note: After transmission completes (MACIsTxReady() returns TRUE),
* the packet can be modified And transmitted again by calling
* MACFlush() again. Until MACPutHeader() Or MACPut() is
* called (in the TX data area), the data in the TX buffer
* will Not be corrupted.
*****************************************************************************)
Public Sub MACFlush()
// Reset the Ethernet TX logic. This is a (suspected) errata workaround to
// prevent the TXRTS bit from getting stuck set indefinitely, causing the
// stack to lock up under certain bad conditions.
ECON1.7 = 1
ECON1.7 = 0
// Wait at least 1.6us after TX Reset before setting TXRTS.
// If you don't wait long enough, the TX logic won't be finished resetting.
DelayUS(2)
EIR.1 = 0
// Start the transmission
// After transmission completes (MACIsTxReady() returns TRUE), the packet
// can be modified and transmitted again by calling MACFlush() again.
// Until MACPutHeader() is called, the data in the TX buffer will not be
// corrupted.
ECON1.3 = 1
//wTXWatchdog = TickGet()
End Sub
(******************************************************************************
* Function: MACSetReadPtrInRx(Word offset)
*
* PreCondition: A packet has been obtained by calling MACGetHeader() And
* getting a TRUE result.
*
* Input: offset: Word specifying how many Bytes beyond the Ethernet
* header's type field to relocate the SPI read
* pointer.
*
* Output: None
*
* Side Effects: None
*
* Overview: SPI Read pointer are updated. All calls To
* MACGet() And MACGetArray() will use these new values.
*
* Note: RXSTOP must be statically defined As being > RXSTART For
* this Function To work correctly. In other Words, do Not
* define an RX buffer which spans the $1FFF->$0000 memory
* boundary.
*****************************************************************************)
Public Sub MACSetReadPtrInRx(offset As Word )
Dim ReadPT As WORD_VAL
// Determine the address of the beginning of the entire packet
// and adjust the address to the desired location
ReadPT.Val = CurrentPacketLocation.Val + SizeOf(ENC_PREAMBLE) + offset
// Since the receive buffer is circular, adjust if a wraparound is needed
If ReadPT.Val > RXSTOP Then
ReadPT.Val = ReadPT.Val - RXSIZE
EndIf
// Set the read pointer to the new calculated value
ERDPTL = ReadPT.v(0)
ERDPTH = ReadPT.v(1)
End Sub
(******************************************************************************
* Function: Word MACSetWritePtr(Word Address)
*
* PreCondition: None
*
* Input: Address: Address To seek To
*
* Output: Word: Old EWRPT location
*
* Side Effects: None
*
* Overview: SPI Write pointer is updated. All calls To
* MACPut() And MACPutArray() will use this new value.
*
* Note: None
*****************************************************************************)
Public Function MACSetWritePtr(address As Word )As Word
Dim oldVal As WORD_VAL
oldVal.v(0) = EWRPTL
oldVal.v(1) = EWRPTH
// Set the SPI write pointer to the new calculated value
EWRPTL = Address.Byte0
EWRPTH = Address.Byte1
result = oldVal.Val
End Function
(******************************************************************************
* Function: Word MACSetReadPtr(Word Address)
*
* PreCondition: None
*
* Input: Address: Address To seek To
*
* Output: Word: Old ERDPT value
*
* Side Effects: None
*
* Overview: SPI Write pointer is updated. All calls To
* MACPut() And MACPutArray() will use this new value.
*
* Note: None
*****************************************************************************)
Public Function MACSetReadPtr(Address As Word) As Word
Dim oldVal As WORD_VAL
oldVal.v(0) = ERDPTL
oldVal.v(1) = ERDPTH
// Set the SPI write pointer to the new calculated value
ERDPTL = Address.Byte0
ERDPTH = Address.Byte1
result = oldVal.Val
End Function
(******************************************************************************
* Function: Word CalcIPBufferChecksum(Word len)
*
* PreCondition: Read buffer pointer set To starting of checksum data
*
* Input: len: Total number of Bytes To calculate the checksum over.
* The first Byte included in the checksum is the Byte
* pointed To by ERDPT, which is updated by calls To
* MACSetReadPtr(), MACGet(), MACGetArray(),
* MACGetHeader(), etc.
*
* Output: 16-Bit checksum As defined by RFC 793
*
* Side Effects: None
*
* Overview: This Function performs a checksum calculation in the MAC
* buffer itself
*
* Note: This Function works either in the RX buffer area Or the TX
* buffer area. No validation is Done on the len parameter.
*****************************************************************************)
Public Function CalcIPBufferChecksum(len As Word) As Word
Dim Start As WORD_VAL
Dim Checksum As DWORD_VAL
Dim ChunkLen, Temp As Word
Dim DataBuffer(20) As Byte // Must be an even size
Dim DataPtr As FSR0
Checksum.Val = $00000000
// Save the SPI read pointer starting address
Start.v(0) = ERDPTL
Start.v(1) = ERDPTH
While Len <> 0
// Obtain a chunk of data (less SPI overhead compared
// to requesting one byte at a time)
If Len > SizeOf(DataBuffer) Then
ChunkLen = SizeOf(DataBuffer)
Else
ChunkLen = Len
EndIf
MACGetArray(@DataBuffer, ChunkLen)
Len = Len - ChunkLen
// Take care of a last odd numbered data byte
If ChunkLen.0 <> 0 Then
DataBuffer(ChunkLen) = $00
Inc(ChunkLen)
EndIf
// Calculate the checksum over this chunk
DataPtr = @DataBuffer
While ChunkLen <> 0
Temp.Byte0 = POSTINC0
Temp.Byte1 = POSTINC0
Checksum.Val = Checksum.Val + Temp
Dec(ChunkLen, 2)
Wend
Wend
// Restore old read pointer location
ERDPTL = Start.v(0)
ERDPTH = Start.v(1)
// Do an end-around carry (one's complement arrithmatic)
Checksum.Val = Checksum.w(0) + Checksum.w(1)
// Do another end-around carry in case if the prior add
// caused a carry out
Checksum.w(0) = Checksum.w(0) + Checksum.w(1)
// Return the resulting checksum
result = Not Checksum.w(0)
End Function
(******************************************************************************
* Function: Word MACCalcRxChecksum(Word offset, Word len)
*
* PreCondition: None
*
* Input: offset - Number of Bytes beyond the beginning of the
* Ethernet data (first Byte after the Type field)
* where the checksum should begin
* len - Total number of Bytes To Include in the checksum
*
* Output: 16-Bit checksum As defined by RFC 793.
*
* Side Effects: None
*
* Overview: This Function performs a checksum calculation in the MAC
* buffer itself
*
* Note: None
*****************************************************************************)
Public Function MACCalcRxChecksum(offset As Word, Len As Word) As Word
Dim temp As WORD_VAL
Dim RDSave As WORD_VAL
// Add the offset requested by firmware plus the Ethernet header
temp.Val = CurrentPacketLocation.Val + SizeOf(ENC_PREAMBLE) + offset
If temp.Val > RXSTOP Then // Adjust value if a wrap is needed
temp.Val = temp.Val - RXSIZE
EndIf
RDSave.v(0) = ERDPTL
RDSave.v(1) = ERDPTH
ERDPTL = temp.v(0)
ERDPTH = temp.v(1)
temp.Val = CalcIPBufferChecksum(Len)
ERDPTL = RDSave.v(0)
ERDPTH = RDSave.v(1)
result = temp.Val
End Function
(******************************************************************************
* Function: MACMemCopyAsync(Word destAddr, Word sourceAddr, Word len)
*
* PreCondition: None
*
* Input: destAddr: Destination address in the Ethernet memory To
* copy To. If the MSb is set, the current EWRPT
* value will be used instead.
* sourceAddr: Source address To Read from. If the MSb is
* set, the current ERDPT value will be used
* instead.
* len: Number of Bytes To copy
*
* Output: None
*
* Side Effects: None
*
* 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.
*****************************************************************************)
Public Sub MACMemCopyAsync(destAddr As Word, sourceAddr As Word, Len As Word)
Dim ReadSave, WriteSave As WORD_VAL
Dim UpdateWritePointer As Boolean
Dim UpdateReadPointer As Boolean
UpdateWritePointer = false
UpdateReadPointer = false
If destAddr.15 <> 0 Then
UpdateWritePointer = true
destAddr.Byte0 = EWRPTL
destAddr.Byte1 = EWRPTH
EndIf
If sourceAddr.15 <> 0 Then
UpdateReadPointer = true
sourceAddr.Byte0 = ERDPTL
sourceAddr.Byte1 = ERDPTH
EndIf
// Handle special conditions where len == 0 or len == 1
// The DMA module is not capable of handling those corner cases
If Len <= 1 Then
If Not UpdateReadPointer Then
ReadSave.v(0) = ERDPTL
ReadSave.v(1) = ERDPTH
EndIf
If Not UpdateWritePointer Then
WriteSave.v(0) = EWRPTL
WriteSave.v(1) = EWRPTH
EndIf
ERDPTL = sourceAddr.Byte0
ERDPTH = sourceAddr.Byte1
EWRPTL = destAddr.Byte0
EWRPTH = destAddr.Byte1
While Len <> 0
MACPut(MACGet())
Dec(Len)
Wend
If Not UpdateReadPointer Then
ERDPTL = ReadSave.v(0)
ERDPTH = ReadSave.v(1)
EndIf
If Not UpdateWritePointer Then
EWRPTL = WriteSave.v(0)
EWRPTH = WriteSave.v(1)
EndIf
Else
If UpdateWritePointer Then
WriteSave.Val = destAddr + Len
EWRPTL = WriteSave.v(0)
EWRPTH = WriteSave.v(1)
EndIf
Len = Len + (sourceAddr - 1)
While DMAST
Wend
EDMASTL = sourceAddr.Byte0
EDMASTH = sourceAddr.Byte1
EDMADSTL = destAddr.Byte0
EDMADSTH = destAddr.Byte1
If (sourceAddr <= RXSTOP) And (Len > RXSTOP) Then //&& (sourceAddr >= RXSTART))
Len = Len - RXSIZE
EndIf
EDMANDL = Len.Byte0
EDMANDH = Len.Byte1
ECON1.4 = 0
ECON1.5 = 1
If UpdateReadPointer Then
Inc(Len)
If (sourceAddr <= RXSTOP) And (Len > RXSTOP) Then //&& (sourceAddr >= RXSTART))
Len = Len - RXSIZE
EndIf
ERDPTL = Len.Byte0
ERDPTH = Len.Byte1
EndIf
EndIf
End Sub
Public Function MACIsMemCopyDone() As Boolean
result = Not DMAST
End Function
(*
******************************************************************************
* Function: void MACPutROMArray(ROM Byte *Val, Word len)
* PreCondition: SPI bus must be initialized (Done in MACInit()).
* EWRPT must point To the location To begin writing.
* Input: *Val: Pointer To source of Bytes To copy.
* len: Number of Bytes To write To the data buffer.
* Output: None
* Side Effects: None
* Overview: MACPutArray writes several sequential Bytes To the
* ENC28J60 RAM. It performs faster than multiple MACPut()
* calls. EWRPT is incremented by len.
* Note: None
*****************************************************************************/
*)
Public Sub MACPutROMArray(Val As TROMAddress, Len As Word)
// Note: Due to a PIC18F97J60 bug, you must use the MOVFF instruction to
// write to EDATA or else the read pointer (ERDPT) will inadvertently
// increment.
While Len <> 0
PRODL = ReadROM(Val) // Start sending the byte
ASM
movff PRODL, EDATA
End ASM
Inc(Val)
Dec(Len)
Wend
End Sub
{******************************************************************************
* Function: MACPowerDown()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: MACPowerDown disables the Ethernet Module.
* All MAC And PHY registers should Not be accessed.
*
* Note: Normally, this Function would be called before putting the
* PIC To sleep. If a packet is being transmitted While this
* Function is called, this Function will block Until it is
* it complete. If anything is being received, it will be
* completed.
*
* The Ethernet Module will Continue To draw significant
* power in sleep mode If this Function is Not called first.
*****************************************************************************}
Sub MACPowerDown()
// Disable packet reception
ECON1.2 = 0
// Make sure any last packet which was in-progress when RXEN was cleared
// is completed
While BUSY Wend
// If a packet is being transmitted, wait for it to finish
While ECON1.3 <> 0 Wend
// Disable the Ethernet module
ECON2.5 = 0
//end MACPowerDown
End Sub
(******************************************************************************
* Function: MACPowerUp()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: MACPowerUp returns the Ethernet Module back To normal operation
* after a previous call To MACPowerDown(). Calling this
* Function when already powered up will have no effect.
*
* Note: If a link partner is present, it will take 10s of
* milliseconds before a new link will be established after
* waking up. While Not linked, packets which are
* transmitted will most likely be lost. MACIsLinked() can
* be called To determine If a link is established.
*****************************************************************************)
Sub MACPowerUp()
// Power up the Ethernet module
ECON2.5 = 1
// Wait for PHY to become ready
While Not PHYClockIsReady Wend
// Enable packet reception
ECON1.2 = 1
//end MACPowerUp
End Sub
Code: Select all
{
*****************************************************************************
* Name : MAC.BAS *
* Date : 28/08/2007 *
* Version : 1.0 - Based around Microchip TCP/IP stack version 4.13 *
* Notes : *
* ========================================================================= *
* Software License Agreement *
* *
* Copyright © 2002-2007 Microchip Technology Inc. All rights reserved. *
* *
* Microchip licenses to you the right to use, modify, copy, and distribute: *
* (i) the Software when embedded on a Microchip microcontroller or digital *
* signal controller product (“Device”) which is integrated into *
* Licensee’s product; or *
* (ii) ONLY the Software driver source files ENC28J60.c and ENC28J60.h *
* ported to a non-Microchip device used in conjunction with a *
* Microchip ethernet controller for the sole purpose of interfacing *
* with the ethernet controller. *
* *
* You should refer to the license agreement accompanying this Software for *
* additional information regarding your rights and obligations. *
* *
* THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF *
* ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY *
* WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND *
* NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP BE LIABLE FOR ANY *
* INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR *
* LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR *
* SERVICES, ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY *
* DEFENSE THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER *
* SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING *
* NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. *
*****************************************************************************
}
Module MAC
// The MAC_TX_BUFFER_COUNT must be equal to MAX_TCP_SOCKETS + 1
// (1 reserved for high priority messages), or else calls to
// TCPPut may fail when multiple TCP sockets have data pending
// in the output buffer that hasn't been ACKed. Changing this
// value is recommended only if the rammifications of doing so
// are properly understood.
#define _MAC_TX_BUFFER_SIZE = (1500)
// This value will change if TCP is enabled...
#ifndef RESERVED_TCP_MEMORY
#define RESERVED_TCP_MEMORY = 0
#endif
#ifndef STACK_USE_HTTP_SERVER
#define RESERVED_HTTP_MEMORY = 0
#endif
#ifndef STACK_USE_SSL_SERVER
#define RESERVED_SSL_MEMORY = 0
#endif
// MAC RAM definitions
#define _RAMSIZE = 8192
#define _TXSTART = (_RAMSIZE - (1 + 1514 +7) - RESERVED_TCP_MEMORY - RESERVED_HTTP_MEMORY - RESERVED_SSL_MEMORY)
#define _RXSTART = (0) // Should be an even memory address; must be 0 for errata
#define _RXSTOP = ((_TXSTART - 2) Or $0001) // Odd for errata workaround
#define _RXSIZE = (_RXSTOP - _RXSTART + 1)
#define _BASE_TX_ADDR = (_TXSTART + 1)
#define _BASE_TCB_ADDR = (_BASE_TX_ADDR + (1514 + 7))
#define _BASE_HTTPB_ADDR = (_BASE_TCB_ADDR + RESERVED_TCP_MEMORY)
#define _BASE_SSLB_ADDR = (_BASE_HTTPB_ADDR + RESERVED_HTTP_MEMORY)
#if _RXSIZE < 1400
#warning "Ethernet RX buffer is tiny. Reduce MAX_TCP_SOCKETS, TCP_TX_FIFO_SIZE, Or TCP_RX_FIFO_SIZE"
#endif
(*
This MAC module is the interface to all other stack modules - none of the
stack modules will interface to a hardware layer (for example, ENC28J60)
directly.
*)
// import ENC28J60
#if _ethernet = 0
Include "ENC28J60.bas"
Public Type
ETHER_HEADER = MAC_ETHER_HEADER
Public Const
MAC_IP = ENC28J60.MAC_IP,
MAC_ARP = ENC28J60.MAC_ARP,
MAC_UNKNOWN = ENC28J60.MAC_UNKNOWN,
MAC_TX_BUFFER_SIZE = ENC28J60.MAC_TX_BUFFER_SIZE,
RAMSIZE = ENC28J60.RAMSIZE,
TXSTART = ENC28J60.TXSTART,
RXSTART = ENC28J60.RXSTART,
RXSTOP = ENC28J60.RXSTOP,
RXSIZE = ENC28J60.RXSIZE,
BASE_TX_ADDR = ENC28J60.BASE_TX_ADDR,
BASE_TCB_ADDR = ENC28J60.BASE_TCB_ADDR,
BASE_HTTPB_ADDR = ENC28J60.BASE_HTTPB_ADDR
Public Dim
MACInit As ENC28J60.MACInit,
MACIsLinked As ENC28J60.MACIsLinked,
MACGetHeader As ENC28J60.MACGetHeader,
MACSetReadPtrInRx As ENC28J60.MACSetReadPtrInRx,
MACSetWritePtr As ENC28J60.MACSetWritePtr,
MACSetReadPtr As ENC28J60.MACSetReadPtr,
MACGet As ENC28J60.MACGet,
MACGetArray As ENC28J60.MACGetArray,
MACDiscardRx As ENC28J60.MACDiscardRx,
MACGetFreeRxSize As ENC28J60.MACGetFreeRxSize,
MACMemCopyAsync As ENC28J60.MACMemCopyAsync,
MACIsMemCopyDone As ENC28J60.MACIsMemCopyDone,
MACPutHeader As ENC28J60.MACPutHeader,
MACIsTxReady As ENC28J60.MACIsTxReady,
MACPut As ENC28J60.MACPut,
MACPutArray As ENC28J60.MACPutArray,
MACPutROMArray As ENC28J60.MACPutROMArray,
MACFlush As ENC28J60.MACFlush,
MACCalcRxChecksum As ENC28J60.MACCalcRxChecksum,
CalcIPBufferChecksum As ENC28J60.CalcIPBufferChecksum
// other implementations go here...
#else
//#error "Ethernet MCUs not implemented. ENC28J60 is the only device currently supported"
(*
It is very important that with any new harware implementation, the types,
constants, functions and subroutines shown above in the ENC28J60 import
section are included
*)
Include "ETH97J60.bas"
Public Type
ETHER_HEADER = MAC_ETHER_HEADER
Public Const
MAC_IP = ETH97J60.MAC_IP,
MAC_ARP = ETH97J60.MAC_ARP,
MAC_UNKNOWN = ETH97J60.MAC_UNKNOWN,
MAC_TX_BUFFER_SIZE = ETH97J60.MAC_TX_BUFFER_SIZE,
RAMSIZE = ETH97J60.RAMSIZE,
TXSTART = ETH97J60.TXSTART,
RXSTART = ETH97J60.RXSTART,
RXSTOP = ETH97J60.RXSTOP,
RXSIZE = ETH97J60.RXSIZE,
BASE_TX_ADDR = ETH97J60.BASE_TX_ADDR,
BASE_TCB_ADDR = ETH97J60.BASE_TCB_ADDR,
BASE_HTTPB_ADDR = ETH97J60.BASE_HTTPB_ADDR
Public Dim
MACInit As ETH97J60.MACInit,
MACIsLinked As ETH97J60.MACIsLinked,
MACGetHeader As ETH97J60.MACGetHeader,
MACSetReadPtrInRx As ETH97J60.MACSetReadPtrInRx,
MACSetWritePtr As ETH97J60.MACSetWritePtr,
MACSetReadPtr As ETH97J60.MACSetReadPtr,
MACGet As ETH97J60.MACGet,
MACGetArray As ETH97J60.MACGetArray,
MACDiscardRx As ETH97J60.MACDiscardRx,
MACGetFreeRxSize As ETH97J60.MACGetFreeRxSize,
MACMemCopyAsync As ETH97J60.MACMemCopyAsync,
MACIsMemCopyDone As ETH97J60.MACIsMemCopyDone,
MACPutHeader As ETH97J60.MACPutHeader,
MACIsTxReady As ETH97J60.MACIsTxReady,
MACPut As ETH97J60.MACPut,
MACPutArray As ETH97J60.MACPutArray,
MACPutROMArray As ETH97J60.MACPutROMArray,
MACFlush As ETH97J60.MACFlush,
MACCalcRxChecksum As ETH97J60.MACCalcRxChecksum,
CalcIPBufferChecksum As ETH97J60.CalcIPBufferChecksum
#endif
now i am finishing the portage of HTTP2.c and MPFS2.c and i am planning to buy a board for testing
ps: i have moved Hi() and Low() subs present in ENC28J60.bas to netutils.bas and make them public for sharing them with ETH97J60.bas