📄 enc28j60.c
字号:
#endif
#if defined(MAC_FILTER_BROADCASTS)
// NOTE: This code has NOT been tested. See StackTsk.h's explanation
// of MAC_FILTER_BROADCASTS.
/******************************************************************************
* Function: void MACSetPMFilter(BYTE *Pattern,
* BYTE *PatternMask,
* WORD PatternOffset)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* MACIsTxReady() must return TRUE
*
* Input: *Pattern: Pointer to an intial pattern to compare against
* *PatternMask: Pointer to an 8 byte pattern mask which
* defines which bytes of the pattern are
* important. At least one bit must be set.
* PatternOffset: Offset from the beginning of the Ethernet
* frame (1st byte of destination address), to
* begin comparing with the given pattern.
*
* Output: None
*
* Side Effects: Contents of the TX buffer space are overwritten
*
* Overview: MACSetPMFilter sets the hardware receive filters for:
* CRC AND (Unicast OR Pattern Match). As a result, only a
* subset of the broadcast packets which are normally
* received will be received.
*
* Note: None
*****************************************************************************/
void MACSetPMFilter(BYTE *Pattern,
BYTE *PatternMask,
WORD PatternOffset)
{
WORD_VAL i;
BYTE *MaskPtr;
BYTE UnmaskedPatternLen;
// Set the SPI write pointer and DMA startting address to the beginning of
// the transmit buffer
BankSel(EWRPTL);
WriteReg(EWRPTL, LOW(TXSTART));
WriteReg(EWRPTH, HIGH(TXSTART));
WriteReg(EDMASTL, LOW(TXSTART));
WriteReg(EDMASTH, HIGH(TXSTART));
// Fill the transmit buffer with the pattern to match against. Only the
// bytes which have a mask bit of 1 are written into the buffer and will
// subsequently be used for checksum computation.
MaskPtr = PatternMask;
for(i.Val = 0x0100; i.v[0] < 64; i.v[0]++)
{
if( *MaskPtr & i.v[1] )
{
MACPut(*Pattern);
UnmaskedPatternLen++;
}
Pattern++;
i.v[1] <<= 1;
if( i.v[1] == 0u )
{
i.v[1] = 0x01;
MaskPtr++;
}
}
// Calculate and set the DMA end address
i.Val = TXSTART + (WORD)UnmaskedPatternLen - 1;
WriteReg(EDMANDL, i.v[0]);
WriteReg(EDMANDH, i.v[1]);
// Calculate the checksum on the given pattern using the DMA module
BFSReg(ECON1, ECON1_DMAST | ECON1_CSUMEN);
while(ReadETHReg(ECON1).ECON1bits.DMAST);
// Make certain that the PM filter isn't enabled while it is
// being reconfigured.
BankSel(ERXFCON);
WriteReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
// Get the calculated DMA checksum and store it in the PM
// checksum registers
i.v[0] == ReadETHReg(EDMACSL).Val;
i.v[1] == ReadETHReg(EDMACSH).Val;
WriteReg(EPMCSL, i.v[0]);
WriteReg(EPMCSH, i.v[0]);
// Set the Pattern Match offset and 8 byte mask
WriteReg(EPMOL, ((WORD_VAL*)&PatternOffset)->v[0]);
WriteReg(EPMOH, ((WORD_VAL*)&PatternOffset)->v[1]);
for(i.Val = EPMM0; i.Val <= EPMM7 ; i.Val++)
{
WriteReg(i.Val, *PatternMask++);
}
// Begin using the new Pattern Match filter instead of the
// broadcast filter
WriteReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN);
}//end MACSetPMFilter
/******************************************************************************
* Function: void MACDisablePMFilter(void)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: MACDisablePMFilter disables the Pattern Match receive
* filter (if enabled) and returns to the default filter
* configuration of: CRC AND (Unicast OR Broadcast).
*
* Note: None
*****************************************************************************/
void MACDisablePMFilter(void)
{
BankSel(ERXFCON);
WriteReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
return;
}//end MACDisablePMFilter
#endif // end of MAC_FILTER_BROADCASTS specific code
/******************************************************************************
* Function: BYTE MACGet()
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* ERDPT must point to the place to read from.
*
* Input: None
*
* Output: Byte read from the ENC28J60's 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 follow the receive buffer wrapping boundary.
*
* Note: None
*****************************************************************************/
BYTE MACGet()
{
BYTE Result;
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = RBM;
while(!ENC_SPI_IF); // Wait until opcode/address is transmitted.
Result = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_SSPBUF = 0; // Send a dummy byte to receive the register
// contents.
while(!ENC_SPI_IF); // Wait until register is received.
Result = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_CS_IO = 1;
return Result;
}//end MACGet
/******************************************************************************
* Function: WORD MACGetArray(BYTE *val, WORD len)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* 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: Burst reads several sequential bytes from the data buffer
* and places them into local memory. With SPI burst support,
* it performs much faster than multiple MACGet() calls.
* ERDPT is incremented after each byte, following the same
* rules as MACGet().
*
* Note: None
*****************************************************************************/
WORD MACGetArray(BYTE *val, WORD len)
{
WORD i;
BYTE Dummy;
// Start the burst operation
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = RBM; // Send the Read Buffer Memory opcode.
i = 0;
val--;
while(!ENC_SPI_IF); // Wait until opcode/address is transmitted.
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
// Read the data
while(i<len)
{
ENC_SSPBUF = 0; // Send a dummy byte to receive a byte
i++;
val++;
while(!ENC_SPI_IF); // Wait until byte is received.
*val = ENC_SSPBUF;
ENC_SPI_IF = 0;
};
// Terminate the burst operation
ENC_CS_IO = 1;
return i;
}//end MACGetArray
/******************************************************************************
* Function: void MACPut(BYTE val)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* EWRPT must point to the location to begin writing.
*
* Input: Byte to write into the ENC28J60 buffer memory
*
* Output: None
*
* Side Effects: None
*
* Overview: MACPut outputs the Write Buffer Memory opcode/constant
* (8 bits) and data to write (8 bits) over the SPI.
* EWRPT is incremented after the write.
*
* Note: None
*****************************************************************************/
void MACPut(BYTE val)
{
BYTE Dummy;
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = WBM; // Send the opcode and constant.
while(!ENC_SPI_IF); // Wait until opcode/constant is transmitted.
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_SSPBUF = val; // Send the byte to be writen.
while(!ENC_SPI_IF); // Wait until byte is transmitted.
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_CS_IO = 1;
}//end MACPut
/******************************************************************************
* Function: void MACPutArray(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
*****************************************************************************/
void MACPutArray(BYTE *val, WORD len)
{
BYTE Dummy;
// Select the chip and send the proper opcode
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = WBM; // Send the Write Buffer Memory opcode
while(!ENC_SPI_IF); // Wait until opcode/constant is transmitted.
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
// Send the data
while(len)
{
ENC_SSPBUF = *val; // Start sending the byte
val++; // Increment after writing to ENC_SSPBUF to increase speed
len--; // Decrement after writing to ENC_SSPBUF to increase speed
while(!ENC_SPI_IF); // Wait until byte is transmitted
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
};
// Terminate the burst operation
ENC_CS_IO = 1;
}//end MACPutArray
/******************************************************************************
* Function: static void SendSystemReset(void)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: SendSystemReset 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
*****************************************************************************/
static void SendSystemReset(void)
{
BYTE Dummy;
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = SR;
while(!ENC_SPI_IF); // Wait until the command is transmitted.
Dummy = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_CS_IO = 1;
}//end SendSystemReset
/******************************************************************************
* Function: REG ReadETHReg(BYTE Address)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* Bank select bits must be set corresponding to the register
* to read from.
*
* Input: 5 bit address of the ETH control register to read from.
* The top 3 bits must be 0.
*
* Output: Byte read from the Ethernet controller's ETH register.
*
* Side Effects: None
*
* Overview: ReadETHReg sends the 8 bit RCR opcode/Address byte over
* the SPI and then retrives the register contents in the
* next 8 SPI clocks.
*
* Note: This routine cannot be used to access MAC/MII or PHY
* registers. Use ReadMACReg() or ReadPHYReg() for that
* purpose.
*****************************************************************************/
static REG ReadETHReg(BYTE Address)
{
REG r;
// Select the chip and send the Read Control Register opcode/address
ENC_CS_IO = 0;
ENC_SPI_IF = 0;
ENC_SSPBUF = RCR | Address;
while(!ENC_SPI_IF); // Wait until the opcode/address is transmitted
r.Val = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_SSPBUF = 0; // Send a dummy byte to receive the register
// contents
while(!ENC_SPI_IF); // Wait until the register is received
r.Val = ENC_SSPBUF;
ENC_SPI_IF = 0;
ENC_CS_IO = 1;
return r;
}//end ReadETHReg
/******************************************************************************
* Function: REG ReadMACReg(BYTE Address)
*
* PreCondition: SPI bus must be initialized (done in MACInit()).
* Bank select bits must be set corresponding to the register
* to read from.
*
* Input: 5 bit address of the MAC or MII register to read from.
* The top 3 bits must be 0.
*
* Output: Byte read from the Ethernet controller's MAC/MII register.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -