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

📄 scceth.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        *data++ =  eth_data[i];
    }
    for (i = data_length; i < ETH_MIN_SIZE; ++i)
    {
        *data++ = 0x00;
    }
    if (data_length < ETH_MIN_SIZE)
    {
        data_length = ETH_MIN_SIZE;
    }

    /*
     * The SCC will compute the CRC for us.
     */

    /*
     * Update the BD and send it off!
     */
    txbd->length = 6 + 6 + 2 + data_length;

    txbd->status = ( 0
        | MPC8XX_BD_SCCETH_TX_STATUS_R
        | 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
        ) ;

    return TRUE;
}

/********************************************************************/
static void
SCC_RECEIVE (NIF *eth_nif)
{
    /*
     * This routine pulls one or more ethernet frames from
     * the ethernet buffers.
     */
    MPC8XX_IMM  *imm = mpc8xx_get_immp();
    MPC8XX_BD *rxbd, *nextbd;
    ETH_ADDR eth_src, eth_dest;
    uint16 eth_type;
    NBUF *frame;
    int i, frame_length;
    uint8 *rdata;
    rxbd = (MPC8XX_BD *)eth_nif->next_receive;
    eth_type = 0;
    frame = NULL;
    frame_length = 0;
    
    do
    {
        if (rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_EMASK)
        {
            /*
             * Record the error and clear this BD for future use.
             */
            ++eth_nif->f_rx_err;

            /*
             * Update pointer to next valid Rx buffer
             */
            goto next_frame;
        }

        rdata = (uint8 *)rxbd->address;
        frame_length = rxbd->length;

        /* receive the frame */
        eth_dest[0] = *rdata++;
        eth_dest[1] = *rdata++;
        eth_dest[2] = *rdata++;
        eth_dest[3] = *rdata++;
        eth_dest[4] = *rdata++;
        eth_dest[5] = *rdata++;

        eth_src[0] = *rdata++;
        eth_src[1] = *rdata++;
        eth_src[2] = *rdata++;
        eth_src[3] = *rdata++;
        eth_src[4] = *rdata++;
        eth_src[5] = *rdata++;

        eth_type = ((*rdata++) << 8);
        eth_type |= *rdata++;

/*
 * FIX !!! This is a temporary solution to prevent sending up
 * un-necessary packets due to the fragile implementation of TFTP.
 */
if ((eth_dest[0] == 0xFF) && (eth_dest[1] == 0xFF) &&
    (eth_dest[2] == 0xFF) && (eth_dest[3] == 0xFF) &&
    (eth_dest[4] == 0xFF) && (eth_dest[5] == 0xFF))
  {
    /*
      printf("RX: Ethernet Broadcast hdr  FF FF FF FF FF FF\n");    
    */
    goto next_frame;
  }


#if 0
    printf("Dst: %02X:%02X:%02X:%02X:%02X:%02X\n",
        eth_dest[0],
        eth_dest[1],
        eth_dest[2],
        eth_dest[3],
        eth_dest[4],
        eth_dest[5]);
    printf("Src: %02X:%02X:%02X:%02X:%02X:%02X\n",
        eth_src[0],
        eth_src[1],
        eth_src[2],
        eth_src[3],
        eth_src[4],
        eth_src[5]);
    printf("Typ: %04X\n", eth_type);
#endif

        if (!nif_proto(eth_nif, eth_type))
            goto next_frame;

#if 0
        not_me = FALSE;
        for (i = 0; i < sizeof(ETH_ADDR); i++)
        {
            if (eth_src[i] != eth_nif->hwa[i])
            {
                not_me = TRUE;
                break;
            }
        }
        if (!not_me)
            goto next_frame;
#endif
        /*
         * Obtain system RAM buffer for the frame.
         */
        if ((frame = nbuf_allocate(frame_length)) == NULL)
        {
          /*
            printf("\n Failed in nbuf_allocate()\n");
          */
          goto next_frame;
        }

        frame_length -= (6 + 6 + 2 + 0/*CRC*/);
        for (i = 0; i < frame_length; ++i)
        {
            frame->data[i] = *rdata++;
        }
        frame->length = frame_length;
        /*
          Check if there is any request to abort
        */
        if (board_getchar_present()) {
          if (board_getchar() == 0x03) 
            {  /* check for ctrl-c */
              printf("\nINFO: SCC received Ctrl-C, abort!\n");
              nbuf_allocate(frame_length);
              eth_nif->f_err=1; 
            }
        }
        nif_proto_handler(eth_nif, eth_type,
            &frame->data[0], frame_length);

        /*
         * This frame has been processed, move on to the next
         */
    next_frame:

        if (board_getchar_present()) {
          if (board_getchar() == 0x03) 
            {  /* check for ctrl-c */
              printf("\nINFO: SCC received Ctrl-C, Abort!\n");
              eth_nif->f_err=1; 
              /*allocate nbuf to allow polling function to read C-c*/
              nbuf_allocate(frame_length);
              nif_proto_handler(eth_nif, eth_type,
                    &frame->data[0], frame_length);
            }
        }

        /*
         * Update pointer to next valid Rx buffer
         */
        rxbd->length = 0;
        if (rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_W)
        {
            rxbd->status = ( 0
                | MPC8XX_BD_SCCETH_RX_STATUS_E
                | MPC8XX_BD_SCCETH_RX_STATUS_W
                | MPC8XX_BD_SCCETH_RX_STATUS_I
                ) ;

            nextbd = &imm->dpram.bd[_BD_SCC_RX_];
        }
        else
        {
            rxbd->status = ( 0
                | MPC8XX_BD_SCCETH_RX_STATUS_E
                | MPC8XX_BD_SCCETH_RX_STATUS_I
                ) ;

            nextbd = rxbd;
            ++nextbd;
        }
        eth_nif->next_receive = (int)nextbd;

        rxbd = nextbd;

    } while (!(rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_E));
}

/********************************************************************/
static void
SCC_START (NIF *eth_nif)
{
    /*
     * This function allows the MPC8XX SCC Ethernet channel to
     * start receiving frames from the network.
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();

    (void)eth_nif;
 
    /*
     * Turn off transmitter by giving graceful stop command.
     */ 
    imm->cp.CPCR = ( 0
        | MPC8XX_CP_CPCR_OPCODE_GR_STOP_TX
        | MPC8XX_CP_CPCR_FLG
        | _MPC8XX_CP_CPCR_CHANNEL_SCCx_
        ) ;
    while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
        ;

    /*
     * 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)
        ;

    /*
     * Enable the Transmitter and Receiver and we're done!
     */
    imm-> _SCC_ .GSMR_L |= ( 0
        | MPC8XX_SCC_GSMR_L_ENR
        | MPC8XX_SCC_GSMR_L_ENT
        ) ;
}

/********************************************************************/
static void
SCC_STOP (NIF *eth_nif)
{
    /*
     * This function stops the MPC8XX SCC Ethernet channel from
     * receiving frames from the network.
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();

    (void)eth_nif;

    /*
     * Turn off the receiver
     */
    imm-> _SCC_ .GSMR_L &= ~MPC8XX_SCC_GSMR_L_ENR;

    /*
     * Turn off transmitter by giving graceful stop command.
     */ 
    imm->cp.CPCR = ( 0
        | MPC8XX_CP_CPCR_OPCODE_GR_STOP_TX
        | MPC8XX_CP_CPCR_FLG
        | _MPC8XX_CP_CPCR_CHANNEL_SCCx_
        ) ;

    /*
     * Wait for completion
     */
#if 0
    while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
        ;
#endif

    board_second_wait(1);
}

/********************************************************************/
int
SCC_HANDLER (void *dev, void *arg)
{
    /*
     * This is the interrupt service routine for SCC Ethernet
     */
    MPC8XX_IMM  *imm = mpc8xx_get_immp();
    MPC8XX_PRAM_SCCETH *sccpram;
    uint16 scce;
    MPC8XX_BD *bd;
    NIF *eth_nif = (NIF *)arg;

    (void)dev;

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

    /*
     * Check the cause of interrupts in SCC
     */
    scce = imm-> _SCC_ .SCCE;

    if (scce == 0)
    {
        return FALSE; /* wasn't me! */
    }

    if (scce & MPC8XX_SCC_ETH_SCCE_GRA)
    {
        /* printf("Graceful Stop\n"); */
    }
    if (scce & MPC8XX_SCC_ETH_SCCE_TXE)
    {
        bd = (MPC8XX_BD *)((uint32)sccpram->scc.TBASE + (uint32)imm);
        printf("TXE, BD->status:  %04X\n",bd->status);
        printf("TXE, BD->length:  %04X\n",bd->length);
        /*
         * Send TRANSMIT RESTART
         */
        while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
            ;
        imm->cp.CPCR = ( 0
            | MPC8XX_CP_CPCR_OPCODE_RESTART_TX
            | _MPC8XX_CP_CPCR_CHANNEL_SCCx_
            | MPC8XX_CP_CPCR_FLG
            ) ;
        while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
            ;

        /*
         * Resend the packet!
         */
        bd->status = ( 0
            | MPC8XX_BD_SCCETH_TX_STATUS_R
            | 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
            ) ;
    }
    if (scce & MPC8XX_SCC_ETH_SCCE_RXF)
    {
        SCC_RECEIVE (eth_nif);
    }
    if (scce & MPC8XX_SCC_ETH_SCCE_BSY)
    {
        /*printf("RX Buf\n");*/
    }
    if (scce & MPC8XX_SCC_ETH_SCCE_TXB)
    {
    }
    if (scce & MPC8XX_SCC_ETH_SCCE_RXB)
    {
        printf("RXE\n");
    }

    /*
     * Clear the interrupt
     */
    imm-> _SCC_ .SCCE = ~0;

    return TRUE;
}

/********************************************************************/
int
mpc8xx_eth_init (NIF *eth_nif)
{
    /*
     * This function initializes the network interface.
     */
    void board_get_ethaddr(uint8 *);

    nif_create (eth_nif, "mpc8xx SCC");
    eth_nif->nic = (void *)mpc8xx_get_immp();
    board_get_ethaddr(&eth_nif->hwa[0]);

    eth_nif->hwa_size = 6;
    eth_nif->mtu = 1500;
    eth_nif->reset = SCC_RESET ;
    eth_nif->start = SCC_START ;
    eth_nif->stop = SCC_STOP ;
    eth_nif->send = SCC_SEND ;
    eth_nif->receive = (void *)SCC_RECEIVE ;

    return TRUE;
}

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

⌨️ 快捷键说明

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