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

📄 scceth.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * File:        scceth.c
 * Purpose:     Driver for MPC8XX Ethernet on SCCx
 *
 * Notes:       This file included by sccXeth.c
 *
 *
 * 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
     */
    for (i = 0; i < data_length; i++)

⌨️ 快捷键说明

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