📄 eth97j60.c
字号:
* Overview: SPI read and write pointers are updated. All calls to
* MACGet(), MACPut(), MACGetArray(), and MACPutArray(),
* and various other functions 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 0x1FFF->0x0000 memory
* boundary.
*****************************************************************************/
void MACSetRxBuffer(WORD offset)
{
WORD_VAL ReadPT;
// 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 )
{
ReadPT.Val -= RXSIZE;
}
// Set the RAM read and write pointers to the new calculated value
ERDPT = ReadPT.Val;
EWRPT = ReadPT.Val;
}
/******************************************************************************
* Function: void MACSetTxBuffer(BUFFER buffer, WORD offset)
*
* PreCondition: None
*
* Input: buffer: BYTE specifying which transmit buffer to seek
* within. If MAC_TX_BUFFER_COUNT <= 1, this
* parameter is not used.
* offset: WORD specifying how many bytes beyond the Ethernet
* header's type field to relocate the SPI read and
* write pointers.
*
* Output: None
*
* Side Effects: None
*
* Overview: SPI read and write pointers are updated. All calls to
* MACGet(), MACPut(), MACGetArray(), and MACPutArray(),
* and various other functions will use these new values.
*
* Note: None
*****************************************************************************/
void MACSetTxBuffer(BUFFER buffer, WORD offset)
{
CurrentTxBuffer = buffer;
// Calculate the proper address. Since the TX memory area is not circular,
// no wrapparound checks are necessary. +1 adjustment is needed because of
// the per packet control byte which preceeds the packet in the TX memory
// area.
#if MAC_TX_BUFFER_COUNT > 1
offset += TxBuffers[buffer].StartAddress.Val + 1 + sizeof(ETHER_HEADER);
#else
offset += TXSTART + 1 + sizeof(ETHER_HEADER);
#endif
// Set the RAM read and write pointers to the new calculated value
ERDPT = offset;
EWRPT = offset;
}
// MACCalcRxChecksum() and MACCalcTxChecksum() use the DMA module to calculate
// checksums. These two functions have been tested.
/******************************************************************************
* 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 using the hardware DMA module
*
* Note: None
*****************************************************************************/
WORD MACCalcRxChecksum(WORD offset, WORD len)
{
WORD_VAL temp;
// Add the offset requested by firmware plus the Ethernet header
temp.Val = CurrentPacketLocation.Val + sizeof(ENC_PREAMBLE) + offset;
if ( temp.Val > RXSTOP ) // Adjust value if a wrap is needed
{
temp.Val -= RXSIZE;
}
// Program the start address of the DMA
EDMAST = temp.Val;
// Set the DMA end address
temp.Val += len-1;
if ( temp.Val > RXSTOP ) // Adjust value if a wrap is needed
{
temp.Val -= RXSIZE;
}
EDMAND = temp.Val;
// Calculate the checksum using the DMA device
ECON1bits.CSUMEN = 1;
ECON1bits.DMAST = 1;
while(ECON1bits.DMAST);
// Swap endianness and return
temp.v[1] = EDMACSL;
temp.v[0] = EDMACSH;
return temp.Val;
}
/******************************************************************************
* Function: WORD MACCalcTxChecksum(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 using the hardware DMA module
*
* Note: None
*****************************************************************************/
WORD MACCalcTxChecksum(WORD offset, WORD len)
{
WORD_VAL temp;
// Program the start address of the DMA, after adjusting for the Ethernet
// header
#if MAC_TX_BUFFER_COUNT > 1
temp.Val = TxBuffers[CurrentTxBuffer].StartAddress.Val + sizeof(ETHER_HEADER)
+ offset + 1; // +1 needed to account for per packet control byte
#else
temp.Val = TXSTART + sizeof(ETHER_HEADER)
+ offset + 1; // +1 needed to account for per packet control byte
#endif
EDMAST = temp.Val;
// Program the end address of the DMA.
temp.Val += len-1;
EDMAND = temp.Val;
// Calcualte the checksum using the DMA device
ECON1bits.CSUMEN = 1;
ECON1bits.DMAST = 1;
while(ECON1bits.DMAST);
// Swap endianness and return
temp.v[1] = EDMACSL;
temp.v[0] = EDMACSH;
return temp.Val;
}
/******************************************************************************
* 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
* MACGet(), MACSetRxBuffer(), MACSetTxBuffer(), 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. The MAC has a hardware DMA module
* which can calculate the checksum faster than software, so
* this function replaces the CaclIPBufferChecksum() function
* defined in the helpers.c file. Through the use of
* preprocessor defines, this replacement is automatic.
*
* Note: This function works either in the RX buffer area or the TX
* buffer area. No validation is done on the len parameter.
*****************************************************************************/
WORD CalcIPBufferChecksum(WORD len)
{
WORD_VAL temp;
// Take care of special cases which the DMA cannot be used for
if(len == 0u)
{
return 0xFFFF;
}
else if(len == 1u)
{
return ~(((WORD)MACGet())<<8);
}
// Set the DMA starting address to the RAM read pointer value
temp.Val = ERDPT;
EDMAST = temp.Val;
// See if we are calculating a checksum within the RX buffer (where
// wrapping rules apply) or TX/unused area (where wrapping rules are
// not applied)
#if RXSTART == 0
if(temp.Val <= RXSTOP)
#else
if(temp.Val >= RXSTART && temp.Val <= RXSTOP)
#endif
{
// Calculate the DMA ending address given the starting address and len
// parameter. The DMA will follow the receive buffer wrapping boundary.
temp.Val += len-1;
if(temp.Val > RXSTOP)
{
temp.Val -= RXSIZE;
}
}
else
{
temp.Val += len-1;
}
// Write the DMA end address
EDMAND = temp.Val;
// Begin the DMA checksum calculation and wait until it is finished
ECON1bits.CSUMEN = 1;
ECON1bits.DMAST = 1;
while(ECON1bits.DMAST);
// Return the resulting good stuff
return EDMACS;
}
/******************************************************************************
* Function: void MACCopyRxToTx(WORD RxOffset, WORD TxOffset, WORD len)
*
* PreCondition: None
*
* Input: RxOffset: Offset in the RX buffer (0=first byte of
* destination MAC address) to copy from.
* TxOffset: Offset in the TX buffer (0=first byte of
* destination MAC address) to copy to.
* len: Number of bytes to copy
*
* Output: None
*
* Side Effects: None
*
* Overview: If the TX logic is transmitting a packet (ECON1.TXRTS is
* set), the hardware will wait until it is finished. Then,
* the DMA module will copy the data from the receive buffer
* to the transmit buffer.
*
* Note: None
*****************************************************************************/
// Remove this line if your application needs to use this
// function. This code has NOT been tested.
#if 0
void MACCopyRxToTx(WORD RxOffset, WORD TxOffset, WORD len)
{
WORD_VAL temp;
temp.Val = CurrentPacketLocation.Val + RxOffset + sizeof(ENC_PREAMBLE);
if ( temp.Val > RXSTOP ) // Adjust value if a wrap is needed
temp.Val -= RXSIZE;
EDMAST = temp.Val;
temp.Val += len-1;
if ( temp.Val > RXSTOP ) // Adjust value if a wrap is needed
temp.Val -= RXSIZE;
EDMAND = temp.Val;
TxOffset += TXSTART+1;
EDMADST = TxOffset;
// Do the DMA Copy. The DMA module will wait for TXRTS to become clear
// before starting the copy.
ECON1bits.CSUMEN = 0;
ECON1bits.DMAST = 1;
while(ECON1bits.DMAST);
}
#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: None
*
* 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 *PMRegister;
BYTE UnmaskedPatternLen;
// Set the RAM write pointer and DMA startting address to the beginning of
// the transmit buffer
EWRPT = TXSTART;
EDMAST = 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 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -