📄 ethernet.c
字号:
/*--------------------------------------------------------------------------
*
* FILE: ethernet.c
** DESCRIPTION:
*
* Exercises SCC1 Ethernet transmit/receive functions, using RX interrupts.
* This program sends 8 Ethernet frames, with each frame containing a
* different data pattern. SCC1 will receive all 8 frames and then vector
* to the external interrupt. In this interrupt, all 8 Rx frames will be
* checked against it's corresponding Tx frame. It also checks for Rx
* errors. If any errors or mismatches exist then the Ethernet LED on the
* ADS 821/860 board will be flashed. If the transfer of data was
* successful the LED will stay lit constantly.
*
* For a high level explanation, please refer to the applications document
* for this example. This is included in the Zip file you received. If you
* are interested in a ADS 860 development/evaluation system, please
* contact your local sales representative.
*
*
* NOTES <<<IMPORTANT: PLEASE READ>>>:
** 1) Specifically Designed to run on 821/860 ADS board.
** 2) DISABLE Data Cache for pages containing Rx/Tx buffers.
** 3) In Internal or External Loopback Mode, the driver tests the
* transmitted information against the received and turns on the
* ETH LED on the ADS board if there is an exact match. If there is
* not a match, then the ETH LED will flash.
** 4) This driver also takes an external interrupt on a full ethernet
* packet reception. If the interrupt handler does not see Received
* Full status (RXF) in the SCC Event register, then it turns on the
* ETH LED to signal an error condition.
*
* 5) If this program is run under BDM, you must first clear the EXTIE
* bit in the DER. Otherwise, the interrupt from the SCC will trap
* you back into the debugger.
** REFERENCES:
*
* 1) MPC860 Users Manual
* 2) PowerPC Microprocessor Family: The Programming Environments for
* 32-Bit Microprocessors
*
* HISTORY:
** 31 JUL 96 saw Initial version.
* 20 FEB 97 sgj Adapted to HDLC from IRDa.
* 22 AUG 97 sgj Debugged and completed.
* 20 NOV 97 jay Complete Modification and Documented
* 07 JAN 98 ecg Adapted to Transparent Mode from HDLC
* 22 JAN 98 ecg Adapted to Ethernet from Transparent Mode
*
*-------------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include "netcomm.h" /* global defines */
#include "mpc860.h" /* IMMR definitions and declarations */
#include "ethernet.h" /* Local header file */
#include "masks860.h" /* Global masks header file */
/***********************/
/* Global Declarations */
/***********************/
EPPC *IMMR; /* IMMR base pointer */
BDRINGS *RxTxBD; /* buffer descriptors base pointer */
/*----------------------------------------------------------*/
/* Set of Data Buffers for Transparent Receive and Transmit */
/* Data. The Rx buffer pools will take up the first 8 */
/* buffers and the Tx buffer pools will take up the last 8. */
/*----------------------------------------------------------*/
LB BufferPool[NUM_RXBDS+NUM_TXBDS];
/*---------------------------------------------------------*/
/* Status parameters of the receive and transmit processes */
/*---------------------------------------------------------*/
UHWORD RxGood; /* Successful RX flag */
UBYTE RxProcIndex; /* keeps track of next BD to process */
/*-----------------------------------------------------*//* Interrupt Handler Code to be moved to Address 0x500 */
/*-----------------------------------------------------*/extern UWORD ExtIntTable[];
/***********************/
/* Function Prototypes */
/***********************/
void InterruptInit(UWORD *, UWORD[]);
void InitBDs(void);
void SCC1Init(void);
void ExtIntHandler(UWORD);
void Main(void);
void LoadTxBuffers(void);
UHWORD BDEmpty(UHWORD);
UHWORD LastBD(UHWORD);
void Ethled(UHWORD);
void FlashEthled(void);
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: main
*
* DESCRIPTION:
*
* Main function for MPC860 Ethernet example code.
*
* EXTERNAL EFFECT:
*
* PARAMETERS: None
*
* RETURNS: None
*
*-------------------------------------------------------------------------*/
void Main()
{
RxGood = TRUE; /* initialize as good */
RxProcIndex = 0; /* initialize */
/*------------------------*/
/* Establish IMMR pointer */
/*------------------------*/
IMMR = (EPPC *)(GetIMMR() & 0xFFFF0000); /* MPC8xx internal register
map */
/*--------------------------------------------------------*/ /* Place External Interrupt Handler Code to Address 0x500 */
/*--------------------------------------------------------*/ InterruptInit((UWORD *) EXT_INT_VECTOR, ExtIntTable);
/***********************************************************/
/* Establish base pointer for Tx and Rx buffer descriptors */
/***********************************************************/
/*--------------------------------------------------------------------*/
/* We add 64 bytes to the start of the buffer descriptors because the */
/* monitor program on our target uses most of the first 64 bytes for */
/* its own buffer descriptors. If you are not using the SDS monitor */
/* with Motorola's ADS development board, you can delete 64 below and */
/* start at the beginning of this particular block of Dual Port RAM. */
/*--------------------------------------------------------------------*/
RxTxBD = (BDRINGS *)(IMMR->udata_bd + 64); /* Get pointer to BD area
on DPRAM */
/*------------------------------------------------*/
/* Load the Tx buffer pool with the test patterns */
/*------------------------------------------------*/
LoadTxBuffers();
/*-------------------------------------------------------------------*/
/* This function defines a number of buffers for an RX and TX buffer */
/* pool, but does not attempt to manage memory. It uses the first */
/* half of the BD pool for RX and the second half for TX. */
/*-------------------------------------------------------------------*/
InitBDs(); /* Initialize RX and TX BDs */
/*-----------------------------------------------------------*/
/* Initialize and enable SCC1 in Ethernet, internal loopback */
/*-----------------------------------------------------------*/
SCC1Init();
/*------------------------------------------------------------------*/
/* Come in to the loop and wait until all frames have been sent and */
/* received. The Ethernet LED on the ADS board will stay lit until */
/* all frames have been received and checked. If there were any */
/* errors the LED will flash. This action is initiated in the */
/* interrupt handler where the checking takes place. */
/*------------------------------------------------------------------*/
while (1)
{
/*-------------------------------------------------------*/
/* Stay in this tight loop if the transfer of data was */
/* successful. If there wasn't success, stay in a tight */
/* loop in the external interrupt handler. */
/*-------------------------------------------------------*/
while (RxGood == TRUE)
{
/*-------------------------------------------------------*/
/* Turn On Ethernet LED to indicate error-free reception */
/*-------------------------------------------------------*/
Ethled(ON);
}
}
} /* End Main */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: InitBDs
*
*
* DESCRIPTION:
*
* Initializes BD rings to point RX BDs to first half of buffer pool and
* TX BDs to second half of buffer pool. This function also initializes the
* buffer descriptors control and data length fields. It also insures that
* transmit and recieve functions are disabled before buffer descriptors
* are initialized.
*
*
* EXTERNAL EFFECTS: Disable Tx/Rx functions. Changes BDs in dual port ram.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-------------------------------------------------------------------------*/
void InitBDs()
{
UHWORD index;
/*********************************************/
/* Disable SCC1 while we program the buffer */
/* descriptors and the parameter RAM. */
/*********************************************/
/*----------------------------------------------------------------*/
/* Clear the ENT/ENR bits in the GSMR -- disable Transmit/Receive */
/*----------------------------------------------------------------*/
IMMR->scc_regs[SCC1_REG].scc_gsmr_l &= 0xFFFFFFCF;
/*--------------------------------------*/
/* Issue Init Stop TX Command for SCC1. */
/*--------------------------------------*/
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
IMMR->cp_cr = CPCR_STOP_TX |
CPCR_SCC1_CH |
CPCR_FLG; /* ISSUE COMMAND */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
/*-------------------*/ /* Initialize RxBDs. */
/*-------------------*/ for (index = 0; index < NUM_RXBDS; index++)
{
/*--------------------------*/
/* Allocate Receive Buffers */
/*--------------------------*/
RxTxBD->RxBD[index].bd_addr = (UBYTE *)&BufferPool[index];
RxTxBD->RxBD[index].bd_length = 0; /* reset */
if( index != (NUM_RXBDS-1) )
{
RxTxBD->RxBD[index].bd_cstatus = 0x8000; /* Empty */
}
else
{
/*-----------------------------------------------------*/ /* Last RX BD. Set the Empty, Wrap, and Interrupt bits */
/*-----------------------------------------------------*/ RxTxBD->RxBD[index].bd_cstatus = 0xB000;
}
}
/*-------------------*/ /* Initialize TxBDs. */
/*-------------------*/ for (index=0; index < NUM_TXBDS; index++)
{
/*------------------------*/
/* load the buffer length */
/*------------------------*/
RxTxBD->TxBD[index].bd_length = (BUFFER_SIZE-4); // 252 bytes
/*--------------------------------------------------------*/
/* load the address of the data buffer in external memory */
/*--------------------------------------------------------*/
RxTxBD->TxBD[index].bd_addr = (UBYTE *)&BufferPool[FIRST_TX_BUF+index];
if( index != (NUM_TXBDS-1) )
{
/*-------------------------------*/
/* Set Ready, PAD, Last, TC bits */
/*-------------------------------*/
RxTxBD->TxBD[index].bd_cstatus = 0xCC00;
}
else
{
/*-----------------------------------------*/
/* Set Ready, PAD, Wrap, Last, and TC bits */
/*-----------------------------------------*/
RxTxBD->TxBD[index].bd_cstatus = 0xEC00;
}
}
} /* end InitBDs */
/*-------------------------------------------------------------------------
*
* FUNCTION NAME: LoadTxBuffers
*
*
* DESCRIPTION:
*
* This function loads all 8 Tx buffers with Ethernet header
* information, followed by the following data patterns:
*
* Buffer 0: 0x55
* Buffer 1: 0xAA
* Buffer 2: 0x00
* Buffer 3: 0xFF
* Buffer 4: Increasing Walking Ones
* Buffer 5: Decreasing Walking Ones
* Buffer 6: Increment from 0
* Buffer 7: Decrement from 255
*
* The Tx buffers are initialized as shown:
*
* | | |
* DEST ADDR | SOURCE ADDR | TYPE\LENGTH | DATA
* (6 bytes) | (6 bytes) | (2 bytes) | (238 bytes)
*
* This results in a total of 252 bytes. Ethernet's 32-bit CRC is
* transmitted after the last data byte, so the Rx buffers receive
* 252 + 4 = 256 bytes.
*
* EXTERNAL EFFECTS:
*
* BufferPool
*
* PARAMETERS: none
*
* RETURNS: none
*
*-------------------------------------------------------------------------*/
void LoadTxBuffers()
{
UHWORD index, pattern;
/*---------------------------------------------------*/
/* Load buffers 0 through 3 with the following data */
/* patterns: */
/* */
/* Buffer[0] = 0x55 */
/* Buffer[1] = 0xAA */
/* Buffer[2] = 0x00 */
/* Buffer[3] = 0xFF */
/*---------------------------------------------------*/
for (index = 12; index < (BUFFER_SIZE-4); index++)
{
BufferPool[FIRST_TX_BUF][index] = 0x55;
BufferPool[FIRST_TX_BUF+1][index] = 0xAA;
BufferPool[FIRST_TX_BUF+2][index] = 0x00;
BufferPool[FIRST_TX_BUF+3][index] = 0xFF;
}
/*-----------------------------------------*/
/* Buffer[4]: Load increasing walking ones */
/*-----------------------------------------*/
for (index = 12,pattern = 1; index < (BUFFER_SIZE-4); index++,pattern<<=1)
{
if (pattern == 0x0100)
pattern = 0x01;
BufferPool[FIRST_TX_BUF+4][index] = pattern;
}
/*-----------------------------------------*/
/* Buffer[5]: Load decreasing walking ones */
/*-----------------------------------------*/
for (index = 12,pattern = 0x80; index < (BUFFER_SIZE-4); index++,pattern>>=1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -