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

📄 scceth.c

📁 Coldfire MCF5282 DBug bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * File:		scceth.c
 * Purpose:		Driver for MPC8XX Ethernet on SCCx
 *
 * Notes:		This file included by sccXeth.c
 *
 * Author:		Eric DeVolder
 * Date:
 *
 * Modifications:
 *
 */

/********************************************************************/

/*
 * In order to use this dBUG driver, the following assumptions are made:
 *
 * Ethernet on SCC1
 * o the appropriate CLKx pins are configured for Eth Tx & Rx clocks
 * o Pin PA14 allocated for SCC1 TXD1
 * o Pin PA15 allocated for SCC1 RXD1
 * o Pin PB19 allocated for SCC1 RTS1
 * o Pin PC10 allocated for SCC1 CD1
 * o Pin PC11 allocated for SCC1 CTS1
 * o the macro BD_SCC1_TX exists for allocating a BD for Eth Tx
 * o the macro BD_SCC1_RX exists for allocating a BD for Eth Rx
 * o the macro BD_SCC1_RX_NUM exists indicating size of Rx pool
 * o the Ethernet transceiver is enabled and in normal mode
 * o the interrupt handler mpc8xx_scc1_handler() is installed elsewhere
 *
 * Ethernet on SCC2
 * o the appropriate CLKx pins are configured for Eth Tx & Rx clocks
 * o Pin PA12 allocated for SCC2 TXD2
 * o Pin PA13 allocated for SCC2 RXD2
 * o Pin PB18 allocated for SCC2 RTS2
 * o Pin PC8  allocated for SCC2 CD2
 * o Pin PC9  allocated for SCC2 CTS2
 * o the macro BD_SCC2_TX exists for allocating a BD for Eth Tx
 * o the macro BD_SCC2_RX exists for allocating a BD for Eth Rx
 * o the macro BD_SCC2_RX_NUM exists indicating size of Rx pool
 * o the Ethernet transceiver is enabled and in normal mode
 * o the interrupt handler mpc8xx_scc2_handler() is installed elsewhere
 *
 * The pin configurations are normally performed in mpcinit.c, and the
 * macros defined in board.h.
 */

#include <dbug.h>
#include "scceth.h"

/********************************************************************/

#if		(defined(SCC1ETH))

#define _BD_SCC_TX_						BD_SCC1_TX
#define _BD_SCC_RX_						BD_SCC1_RX
#define _BD_SCC_RX_NUM_					BD_SCC1_RX_NUM
#define	_MPC8XX_CP_CPCR_CHANNEL_SCCx_	MPC8XX_CP_CPCR_CHANNEL_SCC1
#define SCC_RESET						mpc8xx_scc1_reset
#define SCC_SEND						mpc8xx_scc1_send
#define SCC_RECEIVE						mpc8xx_scc1_receive
#define SCC_START						mpc8xx_scc1_start
#define SCC_STOP						mpc8xx_scc1_stop
#define SCC_HANDLER						mpc8xx_scc1_handler

#elif	(defined(SCC2ETH))

#define _BD_SCC_TX_						BD_SCC2_TX
#define _BD_SCC_RX_						BD_SCC2_RX
#define _BD_SCC_RX_NUM_					BD_SCC2_RX_NUM
#define	_MPC8XX_CP_CPCR_CHANNEL_SCCx_	MPC8XX_CP_CPCR_CHANNEL_SCC2
#define SCC_RESET						mpc8xx_scc2_reset
#define SCC_SEND						mpc8xx_scc2_send
#define SCC_RECEIVE						mpc8xx_scc2_receive
#define SCC_START						mpc8xx_scc2_start
#define SCC_STOP						mpc8xx_scc2_stop
#define SCC_HANDLER						mpc8xx_scc2_handler

#else
#error "Unsupported configuration"
#endif

/********************************************************************/

/*
 * Local buffers for DMA'ing Ethernet frames
 */

/* The ELB must be long aligned */
typedef uint32
ELB[1520/4];

static ELB
erx_buf[ _BD_SCC_RX_NUM_ ];
 
static ELB
etx_buf;


/********************************************************************/
static int
SCC_RESET (NIF *eth_nif)
{
	/*
	 * This routine initializes the SCC for Ethernet, 10Mbit/S.
	 * The receiver and transmitter are disabled upon exit.
	 */
	MPC8XX_IMM	*imm = mpc8xx_get_immp();
	MPC8XX_SCC *scc;
	MPC8XX_PRAM_SCCETH *sccpram;
	MPC8XX_BD	*rxbd, *txbd;
	unsigned int i;

	scc = (MPC8XX_SCC *)&imm-> _SCC_ ;
	sccpram = (MPC8XX_PRAM_SCCETH *)&imm->dpram. _SCC_ ;

#if	(defined(SCC1ETH))

	/*
	 * Configure SCC1 pins
	 */
	imm->portio.PAPAR |= ( 0
		| MPC8XX_PORTIO_PAPAR_PA14 /* PA14=1, TXD1 */
		| MPC8XX_PORTIO_PAPAR_PA15 /* PA15=1, RXD1 */
		) ;

	imm->portio.PADIR &= ~( 0
		| MPC8XX_PORTIO_PADIR_PA14 /* PA14=0, TXD1 */
		| MPC8XX_PORTIO_PADIR_PA15 /* PA15=0, RXD1 */
		) ;

	imm->portio.PAODR &= ~( 0
		| MPC8XX_PORTIO_PAODR_PA14	/* PA14=0, Active	*/
		| 0									/* Bit 15 reserved	*/
		) ;

	imm->pip.PBPAR &= ~( 0
		| MPC8XX_PIP_PBPAR_PB19 /* PB19=0, input until configed */
		) ;

	imm->pip.PBDIR &= ~( 0
		| MPC8XX_PIP_PBDIR_PB19 /* PB19=0, input until configed */
		) ;

	imm->portio.PCPAR &= ~( 0
		| MPC8XX_PORTIO_PCPAR_PC10 /* PC10=0, CD1  */
		| MPC8XX_PORTIO_PCPAR_PC11 /* PC11=0, CTS1 */
		) ;

	imm->portio.PCDIR &= ~( 0
		| MPC8XX_PORTIO_PCDIR_PC10 /* PC10=0, CD1  */
		| MPC8XX_PORTIO_PCDIR_PC11 /* PC11=0, CTS1 */
		) ;

	imm->portio.PCSO |= ( 0
		| MPC8XX_PORTIO_PCSO_PC10 /* PC10=1, CD1  */
		| MPC8XX_PORTIO_PCSO_PC11 /* PC11=1, CTS1 */
		) ;

#endif

#if	(defined(SCC2ETH))

	/*
	 * Configure SCC2 pins
	 */
	imm->portio.PAPAR |= ( 0
		| MPC8XX_PORTIO_PAPAR_PA12 /* PA12=1, TXD2 */
		| MPC8XX_PORTIO_PAPAR_PA13 /* PA13=1, RXD2 */
		) ;

	imm->portio.PADIR &= ~( 0
		| MPC8XX_PORTIO_PADIR_PA12 /* PA12=0, TXD2 */
		| MPC8XX_PORTIO_PADIR_PA13 /* PA13=0, RXD2 */
		) ;

	imm->portio.PAODR &= ~( 0
		| MPC8XX_PORTIO_PAODR_PA12  /* PA12=0, Active   */
		| 0						 /* Bit 13 reserved  */
		) ;

	imm->pip.PBPAR &= ~( 0
		| MPC8XX_PIP_PBPAR_PB18 /* PB18=0, input until configed */
		) ;

	imm->pip.PBDIR &= ~( 0
		| MPC8XX_PIP_PBDIR_PB18 /* PB18=0, input until configed */
		) ;

	imm->portio.PCPAR &= ~( 0
		| MPC8XX_PORTIO_PCPAR_PC8   /* PC8=0, CD2  */
		| MPC8XX_PORTIO_PCPAR_PC9   /* PC9=0, CTS2 */
		) ;

	imm->portio.PCDIR &= ~( 0
		| MPC8XX_PORTIO_PCDIR_PC8   /* PC8=0, CD2  */
		| MPC8XX_PORTIO_PCDIR_PC9   /* PC9=0, CTS2 */
		) ;

	imm->portio.PCSO |= ( 0
		| MPC8XX_PORTIO_PCSO_PC8	/* PC8=1, CD2  */
		| MPC8XX_PORTIO_PCSO_PC9	/* PC9=1, CTS2 */
		) ;

#endif

	/*
	 * Setup buffers for use by SCC
	 */
	txbd = &imm->dpram.bd[ _BD_SCC_TX_ ];
	txbd->status = ( 0
		| MPC8XX_BD_SCCETH_TX_STATUS_PAD
		| MPC8XX_BD_SCCETH_TX_STATUS_W
		| MPC8XX_BD_SCCETH_TX_STATUS_I
		| MPC8XX_BD_SCCETH_TX_STATUS_L
		| MPC8XX_BD_SCCETH_TX_STATUS_TC
		) ;
	txbd->length = 0;
	txbd->address = (uint32)&etx_buf;

	rxbd = &imm->dpram.bd[ _BD_SCC_RX_ ];
	eth_nif->next_receive = (int)rxbd;	/* point to first rx buf */
	for (i = 0; i < _BD_SCC_RX_NUM_; ++i)
	{
		rxbd->status = ( 0
			| MPC8XX_BD_SCCETH_RX_STATUS_E
			| MPC8XX_BD_SCCETH_RX_STATUS_I
			) ;
		rxbd->length = 0;
		rxbd->address = (uint32)&erx_buf[i];

		++rxbd;
	}
	/*
	 * Mark last receive buffer
	 */
	--rxbd;
	rxbd->status |= MPC8XX_BD_SCCETH_RX_STATUS_W;

	/*
	 * Ethernet Parameter RAM
	 */
	sccpram->scc.RFCR = MPC8XX_PRAM_SCC_FCR_BO_BE;
	sccpram->scc.TFCR = MPC8XX_PRAM_SCC_FCR_BO_BE;
	sccpram->scc.MRBLR = 1520;
	sccpram->scc.TBASE = (uint16)((uint32)&imm->dpram.bd[_BD_SCC_TX_]);
	sccpram->scc.RBASE = (uint16)((uint32)&imm->dpram.bd[_BD_SCC_RX_]);
	sccpram->eth.C_PRES = ~0;
	sccpram->eth.C_MASK = 0xdebb20e3;
	sccpram->eth.CRCEC = 0;
	sccpram->eth.ALEC = 0;
	sccpram->eth.DISFC = 0;
	sccpram->eth.PADS = 0;
	sccpram->eth.RET_LIM = 15;
	sccpram->eth.MFLR = 1520;
	sccpram->eth.MAXD1 = 1520;
	sccpram->eth.MAXD2 = 1520;
	sccpram->eth.MINFLR = ETH_MIN_SIZE;
	sccpram->eth.GADDR1 = 0;
	sccpram->eth.GADDR2 = 0;
	sccpram->eth.GADDR3 = 0;
	sccpram->eth.GADDR4 = 0;
	sccpram->eth.P_PER = 0;
	sccpram->eth.IADDR1 = 0;
	sccpram->eth.IADDR2 = 0;
	sccpram->eth.IADDR3 = 0;
	sccpram->eth.IADDR4 = 0;
	sccpram->eth.TADDR_H = 0;
	sccpram->eth.TADDR_M = 0;
	sccpram->eth.TADDR_L = 0;
	sccpram->eth.PADDR1_L = (eth_nif->hwa[1] << 8) | eth_nif->hwa[0];
	sccpram->eth.PADDR1_M = (eth_nif->hwa[3] << 8) | eth_nif->hwa[2];
	sccpram->eth.PADDR1_H = (eth_nif->hwa[5] << 8) | eth_nif->hwa[4];

	/*
	 * Initialize Tx and Rx Parameters and wait for Ack
	 */
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;
	imm->cp.CPCR = ( 0
		| MPC8XX_CP_CPCR_OPCODE_INIT_RX_TX
		| _MPC8XX_CP_CPCR_CHANNEL_SCCx_
		| MPC8XX_CP_CPCR_FLG
		) ;
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;

	/*
	 * Configured RTS _after_ SCC is configured, otherwise
	 * errant transmissions occur!
	 */
#if (defined(SCC1ETH))
	imm->pip.PBPAR |= MPC8XX_PIP_PBPAR_PB19;
	imm->pip.PBDIR |= MPC8XX_PIP_PBDIR_PB19;
#endif
#if (defined(SCC2ETH))
	imm->pip.PBPAR |= MPC8XX_PIP_PBPAR_PB18;
	imm->pip.PBDIR |= MPC8XX_PIP_PBDIR_PB18;
#endif

	/*
	 * Clear SCC Events
	 */ 
	scc->SCCE = ~0;

	/*
	 * Enable ALL Ethernet interrupts
	 */
	scc->SCCM = ( 0
		| MPC8XX_SCC_ETH_SCCM_GRA
		| MPC8XX_SCC_ETH_SCCM_TXE
		| MPC8XX_SCC_ETH_SCCM_RXF
		| MPC8XX_SCC_ETH_SCCM_BSY
		| MPC8XX_SCC_ETH_SCCM_TXB
		| MPC8XX_SCC_ETH_SCCM_RXB
		) ;

	/*
	 * Initialize DSR
	 */
	scc->DSR = MPC8XX_SCC_ETH_DSR;

	/*
	 * Initialize the PSMR
	 */
	scc->PSMR = ( 0
		| MPC8XX_SCC_ETH_PSMR_CRC_32BIT
/*		| MPC8XX_SCC_ETH_PSMR_PRO */
		| MPC8XX_SCC_ETH_PSMR_NIB_22
		) ;

	/*
	 * Configure SCC as Ethernet
	 */
	scc->GSMR_H = 0;
	scc->GSMR_L = ( 0
		| MPC8XX_SCC_GSMR_L_TCI
		| MPC8XX_SCC_GSMR_L_TPL_48BIT
		| MPC8XX_SCC_GSMR_L_TPP_10
		| MPC8XX_SCC_GSMR_L_TDCR_1X
		| MPC8XX_SCC_GSMR_L_RDCR_1X
		| MPC8XX_SCC_GSMR_L_RENC_NRZ
		| MPC8XX_SCC_GSMR_L_TENC_NRZ
		| MPC8XX_SCC_GSMR_L_MODE_ETHERNET
		) ;

	return TRUE;
}

/********************************************************************/
static int
SCC_SEND (
	NIF *		eth_nif,
	HWA_ADDR_P	eth_dest,
	HWA_ADDR_P	eth_src,
	uint16		eth_type,
	int			data_length,
	uint8		*eth_data
)
{
	/*
	 * This routine transmits a frame over the ethernet.
	 */
	MPC8XX_IMM	*imm = mpc8xx_get_immp();
	MPC8XX_PRAM_SCCETH *sccpram;
	MPC8XX_BD *txbd;
	int i;
	uint8 *data;

	(void)eth_nif;

	sccpram = (MPC8XX_PRAM_SCCETH *)&imm->dpram. _SCC_ ;

	txbd = (MPC8XX_BD *)((uint32)sccpram->scc.TBASE + (uint32)imm);

	/*
	 * Make sure buffer is available before proceeding.
	 */
	 while (txbd->status & MPC8XX_BD_SCCETH_TX_STATUS_R)
		;

	data = (uint8 *)txbd->address;

	/*
	 * Write the destination address
	 */
	*data++ = eth_dest[0];
	*data++ = eth_dest[1];
	*data++ = eth_dest[2];
	*data++ = eth_dest[3];
	*data++ = eth_dest[4];
	*data++ = eth_dest[5];

	/*
	 * Write the source address
	 */
	*data++ = eth_src[0];
	*data++ = eth_src[1];
	*data++ = eth_src[2];
	*data++ = eth_src[3];
	*data++ = eth_src[4];
	*data++ = eth_src[5];

	/*
	 * Write the type code
	 */
	*data++ = ((eth_type &0xFF00) >> 8);
	*data++ =  (eth_type &0x00FF);

	/*
	 * Write the data, the SCC will automatically pad
	 */

⌨️ 快捷键说明

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