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

📄 1

📁 aesop s3c2440a BSP for windowsce 6.0
💻
📖 第 1 页 / 共 4 页
字号:
                        bits[clk_idx++] = MII_MDOE;

                /* Shift to next lowest bit */
                mask >>= 1;
        }

        /* Output the phy register number, msb first */
        mask = (BYTE) 0x10;
        for (i = 0; i < 5; ++i) {
                if (phyreg & mask)
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
                else
                        bits[clk_idx++] = MII_MDOE;

                /* Shift to next lowest bit */
                mask >>= 1;
        }

        /* Tristate and turnaround (2 bit times) */
        bits[clk_idx++] = 0;
        bits[clk_idx++] = 0;

        /* Write out 16 bits of data, msb first */
        mask = 0x8000;
        for (i = 0; i < 16; ++i) {
                if (phydata & mask)
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
                else
                        bits[clk_idx++] = MII_MDOE;

                /* Shift to next lowest bit */
                mask >>= 1;
        }
        /* Final clock bit (tristate) */
        bits[clk_idx++] = 0;

        /* Save the current bank */
        oldBank = ReadWord(BANKSEL_REG);

        /* Select bank 3 */
        WriteWord( BANKSEL_REG, BANK3 );

        /* Get the current MII register value */
        mii_reg = ReadWord (MII_REG);

        /* Turn off all MII Interface bits */
        mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);

        /* Clock all cycles */
        for (i = 0; i < sizeof bits; ++i) {
                /* Clock Low - output data */
                WriteWord ( MII_REG, mii_reg | bits[i]);
                smc_udelay (SMC_PHY_CLOCK_DELAY);


                /* Clock Hi - input data */
                WriteWord ( MII_REG, mii_reg | bits[i] | MII_MCLK);
                smc_udelay (SMC_PHY_CLOCK_DELAY);
                bits[i] |= ReadWord (MII_REG) & MII_MDI;
        }

        /* Return to idle state */
        /* Set clock to low, data to low, and output tristated */
        WriteWord ( MII_REG, mii_reg);
        smc_udelay (SMC_PHY_CLOCK_DELAY);

        /* Restore original bank select */
        WriteWord( BANKSEL_REG, oldBank );

}



#if 1

#if 1
static void smc_wait_ms(unsigned int ms)
{
    volatile int i;
    unsigned int i2;
    
    for(i2=0 ; i2 < ms ; i2++)
    {
       for(i=0 ; i < 1000 ; i++)
       {
       }
    }   
}
#endif


#if 1
#define RPC_REG         0x000A
#define RPC_SPEED       0x2000  /* When 1 PHY is in 100Mbps mode. */
#define RPC_DPLX        0x1000  /* When 1 PHY is in Full-Duplex Mode */
#define RPC_ANEG        0x0800  /* When 1 PHY is in Auto-Negotiate Mode */
#define RPC_LSXA_SHFT   5       /* Bits to shift LS2A,LS1A,LS0A to lsb */
#define RPC_LSXB_SHFT   2       /* Bits to get LS2B,LS1B,LS0B to lsb */
#define RPC_LED_100_10  (0x00)  /* LED = 100Mbps OR's with 10Mbps link detect */
#define RPC_LED_RES     (0x01)  /* LED = Reserved */
#define RPC_LED_10      (0x02)  /* LED = 10Mbps link detect */
#define RPC_LED_FD      (0x03)  /* LED = Full Duplex Mode */
#define RPC_LED_TX_RX   (0x04)  /* LED = TX or RX packet occurred */
#define RPC_LED_100     (0x05)  /* LED = 100Mbps link dectect */
#define RPC_LED_TX      (0x06)  /* LED = TX packet occurred */
#define RPC_LED_RX      (0x07)  /* LED = RX packet occurred */
#define RPC_DEFAULT     ( RPC_SPEED | RPC_DPLX | RPC_ANEG       \
                        | (RPC_LED_100_10 << RPC_LSXA_SHFT)     \
                        | (RPC_LED_TX_RX << RPC_LSXB_SHFT)      )
#endif

static void smc_phy_configure ()
{
#if 1
        int timeout;
        BYTE phyaddr;
        WORD my_phy_caps;       /* My PHY capabilities */
        WORD my_ad_caps;        /* My Advertised capabilities */
        WORD status = 0;        /*;my status = 0 */
        int failed = 0;



        EdbgOutputDebugString("smc_phy_configure()\r\n");
        EdbgOutputDebugString("phy cfg reg1: 0x%x\n", smc_read_phy_register(PHY_CFG1_REG) );


        /* Get the detected phy address */
        phyaddr = SMC_PHY_ADDR;



        /* Reset the PHY, setting all other bits to zero */
        smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_RST);
        timeout = 6;            /* Wait up to 3 seconds */
        while (timeout--) {
                if (!(smc_read_phy_register (PHY_CNTL_REG) & PHY_CNTL_RST)) {
                        /* reset complete */
                        break;
                }

                smc_wait_ms (500);      /* wait 500 millisecs */
        }


        if (timeout < 1) {
                EdbgOutputDebugString ("%s:PHY reset timed out\n", SMC_DEV_NAME);
                goto smc_phy_configure_exit;
        }

        /* Read PHY Register 18, Status Output */
        /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */
        /* Enable PHY Interrupts (for register 18) */
        /* Interrupts listed here are disabled */

        smc_write_phy_register (PHY_MASK_REG, 0x0000);

        smc_wait_ms (500);      /* wait 500 millisecs */






        /* Configure the Receive/Phy Control register */
WriteWord( BANKSEL_REG, BANK0 );        
        WriteWord ( RPC_REG ,RPC_DEFAULT);

        /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
        my_phy_caps = smc_read_phy_register (PHY_STAT_REG);
        my_ad_caps = PHY_AD_CSMA;       /* I am CSMA capable */

        if (my_phy_caps & PHY_STAT_CAP_T4) {
                my_ad_caps |= PHY_AD_T4;
        }
        if (my_phy_caps & PHY_STAT_CAP_TXF) {
                my_ad_caps |= PHY_AD_TX_FDX;
        }
        if (my_phy_caps & PHY_STAT_CAP_TXH) {
                my_ad_caps |= PHY_AD_TX_HDX;
        }
        if (my_phy_caps & PHY_STAT_CAP_TF) {
                my_ad_caps |= PHY_AD_10_FDX;
        }
        if (my_phy_caps & PHY_STAT_CAP_TH) {
                my_ad_caps |= PHY_AD_10_HDX;
        }
        /* Update our Auto-Neg Advertisement Register */
        smc_write_phy_register (PHY_AD_REG, my_ad_caps);

        /* Read the register back.  Without this, it appears that when */
        /* auto-negotiation is restarted, sometimes it isn't ready and */
        /* the link does not come up. */
        smc_read_phy_register(PHY_AD_REG);

        EdbgOutputDebugString ("%s:phy caps=0x%x\n", SMC_DEV_NAME, my_phy_caps);      /*0x7809*/
        EdbgOutputDebugString ("%s:phy advertised caps=0x%x\n", SMC_DEV_NAME, my_ad_caps);    /*0x01e1*/

        /* Restart auto-negotiation process in order to advertise my caps */
        smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);



        /* Wait for the auto-negotiation to complete.  This may take from */
        /* 2 to 3 seconds. */
        /* Wait for the reset to complete, or time out */
        timeout = 20;           /* Wait up to 10 seconds */
        while (timeout--) {
                status = smc_read_phy_register (PHY_STAT_REG);
                if (status & PHY_STAT_ANEG_ACK) {
                        EdbgOutputDebugString ("%s:PHY auto-negotiate complete\n", SMC_DEV_NAME);
                        /* auto-negotiate complete */
                        break;
                }

                smc_wait_ms (500);      /* wait 500 millisecs */

                /* Restart auto-negotiation if remote fault */
                if (status & PHY_STAT_REM_FLT) {
                        EdbgOutputDebugString ("%s:PHY remote fault detected\n", SMC_DEV_NAME);

                        /* Restart auto-negotiation */
                        EdbgOutputDebugString("%s:PHY restarting auto-negotiation\n",SMC_DEV_NAME);
                        smc_write_phy_register (PHY_CNTL_REG,
                                                PHY_CNTL_ANEG_EN |
                                                PHY_CNTL_ANEG_RST |
                                                PHY_CNTL_SPEED |
                                                PHY_CNTL_DPLX);
                }
        }

        EdbgOutputDebugString ("%s:PHY_STAT_REG : 0x%x\n", SMC_DEV_NAME, status);
        if (timeout < 1) {
                EdbgOutputDebugString("%s:PHY auto-negotiate timed out\n", SMC_DEV_NAME);
                EdbgOutputDebugString("%s:PHY auto-negotiate timed out\n", SMC_DEV_NAME);
                failed = 1;
        }

        /* Fail if we detected an auto-negotiate remote fault */
        if (status & PHY_STAT_REM_FLT) 
        {
                EdbgOutputDebugString("PHY remote fault detected\n");
                failed = 1;
        }

        /* Re-Configure the Receive/Phy Control register */
        WriteWord( RPC_REG,RPC_DEFAULT);
        EdbgOutputDebugString("%s:RPC_DEFAULT : 0x%x\n", SMC_DEV_NAME, RPC_DEFAULT);
#endif

smc_phy_configure_exit:
return;

}

#endif





BOOL
SMCInit( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3]) {

    DWORD dwStartTime;
    USHORT wBSR, wConfig;
EdbgOutputDebugString ( "\r\n test1 \r\n");    
    if (! pbBaseAddress)
        return FALSE;
    
    pbEthernetBase = pbBaseAddress;
    dwRegisterMultiplier = dwMultiplier;

    // DANGER - May have to wait 750 usec after reset while EEPROM info loads (Pg 50 of the SMC91C94 spec).
    // until this occurs, SMC registers are inaccessible.
    EdbgOutputDebugString("+SMCInit\r\n");

    
    WriteWord( BANKSEL_REG, BANK1 );
    
    dwStartTime = OEMEthGetSecs();
    while( ReadWord( CONTROL_REG ) & 0x0003 && OEMEthGetSecs() - dwStartTime < 2);

    // Verify the I/O base.  The upper byte of the BSR always reads 0x33, use this.
    // For Odo, the bus cycles will time out and garbage values will be returned.
    wBSR = ReadWord(BANKSEL_REG);
EdbgOutputDebugString ("==%x\n",*(volatile UINT16 *)0xA700030e);
    if ((wBSR & 0xFF00) != 0x3300) {
        EdbgOutputDebugString("SMC card not detected, I/O base 0x%X, BSR: 0x%X\n",pbEthernetBase,wBSR);
        return FALSE;
    }
    EdbgOutputDebugString( "SMC Ethernet card detected at I/O base 0x%X\r\n",pbEthernetBase);

    // Read the MAC address from the 91C94.  This should have been read in from the EEPROM during reset
#if 0    
	if( NULL != MacAddr ) {
	    WriteWord( BANKSEL_REG, BANK1 );
	    MacAddr[0] = ReadWord( MACADDR_REG0 );
	    MacAddr[1] = ReadWord( MACADDR_REG1 );
	    MacAddr[2] = ReadWord( MACADDR_REG2 );
    	EdbgOutputDebugString("SMC Ethernet Address: %B:%B:%B:%B:%B:%B\r\n",
        	                  MacAddr[0] & 0x00FF, MacAddr[0] >> 8,
            	              MacAddr[1] & 0x00FF, MacAddr[1] >> 8,
                	          MacAddr[2] & 0x00FF, MacAddr[2] >> 8);
	}
#endif

    // Set SQUELCH bit - this changes the threshold for a valid signal from 300mV to 180mV.
    // This is to attempt to fix problems we have seen with some (usually 8 port) hubs.
    wConfig = ReadWord(CONFIG_REG);
    wConfig |= CFG_SETSQLCH|CFG_NO_WAIT;
//khryu---------------------------------------------------------------------------------
    #define CONFIG_EPH_POWER_EN 0x8000
    wConfig = CONFIG_EPH_POWER_EN;
//khryu
    
    WriteWord(CONFIG_REG, wConfig);
    EdbgOutputDebugString("SMC config reg val: %X\n",wConfig);
    
    // Initialize the control register
    WriteWord( BANKSEL_REG, BANK1 );
    WriteWord( CONTROL_REG, CONTROL_REG_INIT );

    // Initialize memory configuration register
    WriteWord( BANKSEL_REG, BANK0 );
    WriteWord( MCR_REG, MCR_REG_INIT );

    // Initialize transmit control register
    WriteWord( BANKSEL_REG, BANK0 );
    WriteWord( TCR_REG, TCR_REG_INIT );

    // Initialize interrupt mask register (all ints disabled to start)
    WriteWord( BANKSEL_REG, BANK2 );
    WriteWord( INTERRUPT_REG, 0);

    // The receive register should be the last thing initialzed so that we don't start
    //  getting Frames before we're ready for them.
    
    // Initialize the Receive Control Register (Pg 39 of the SMC91C94 spec):
    WriteWord( BANKSEL_REG, BANK0 );
    WriteWord( RCR_REG, RCR_REG_INIT );

#define RCR_RXEN        0x0100  /* IFF this is set, we can receive packets */
#define RCR_STRIP_CRC   0x0200  /* When set strips CRC from rx packets */

    WriteWord( RCR_REG, (RCR_RXEN|RCR_STRIP_CRC) );

⌨️ 快捷键说明

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