enetphy.c
来自「eCos操作系统源码」· C语言 代码 · 共 381 行
C
381 行
//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2002 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####/*------------------------------------------------------------------- ** FILE: enetPHY.c** DESCRIPTION: GPIO Management Pins driver for the LXT970a * ** Modified for the mpc8260 VADS board*--------------------------------------------------------------------*/#include "types.h"#include <cyg/hal/hal_intr.h> /* HAL_DELAY_US */#include "EnetPHY.h"/* Internal functions */void MdioSend(UINT32, UINT16);UINT16 MdioReceive(UINT16);UINT16 MdioFrame(MDIORW, UINT16, UINT16, UINT32);VUINT32 * pPortDir;VUINT32 * pPortData;/*-------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION:** EXTERNAL EFFECT: Turns on the LXT970 transciever** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**-------------------------------------------------------------------*/void EnableResetPHY(volatile t_BCSR *pBCSR){#ifdef CYGPKG_HAL_POWERPC_TS6#define ETH_RST_MASK 0x20 /* The FPGA control register on the TS6 board uses the same memory * location as the BCSR register on the VADS board. */ volatile cyg_uint32 *fpga_ctrl = (cyg_uint32 *) pBCSR; volatile cyg_uint32 *fpga_vers; cyg_uint32 value; fpga_vers = fpga_ctrl + 1; value = *fpga_vers; if(value >= 6){ /* version 06 of the FPGA added PHY reset control */ value = *fpga_ctrl; /* Set the PHY reset bit */ value |= ETH_RST_MASK; *fpga_vers = value; /* Give the PHY time to reset */ HAL_DELAY_US(10000); /* Clear the reset bit */ *fpga_vers = value & ~ETH_RST_MASK; }#else // active low FETHIEN on BSCR1, assert reset low pBCSR->bcsr1 &= ~(FETHIEN_ | FETHRST_); // de-assert reset pBCSR->bcsr1 |= FETHRST_; #endif}/*-------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION: Writes parameters to the control registers of LXT970** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**-------------------------------------------------------------------*/UINT16 InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link){ VUINT16 FrameValue; /* 8101 Ethernet Management Pin Assignments */ pPortDir = pdir; pPortData = pdat; (*pPortDir) |= MDC_PIN_MASK; /* MD_Clock will always be output only */ /* Test MDC & MDIO Pin Connection to PHY */ MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame FrameValue = MdioFrame(READ, 0, MIRROR_REG, 0); //read test frame if (FrameValue != MD_TEST_FRAME) return LINKERROR; //test data integrity /* General Configuration */ MdioFrame(WRITE, 0, CONFIG_REG, 0x0000); if(link == HUNDRED_HD) MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0081); //100 Mbps Half, 802.3 else MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0021); //10 Mbps Half, 802.3 // 100 Mbps full duplex not supported // MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0101); //100 Mbps Full, 802.3 MdioFrame(WRITE, 0, CONTROL_REG, 0x1300); return 0;}/*-------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION:** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**-------------------------------------------------------------------*/UINT16 EthernetPHYInterruptHandler(){ // Reading registers 1 and 18 in sequence // clears the transceiver interrupt MdioFrame(READ, 0, STATUS_REG, 0); MdioFrame(READ, 0, INT_STAT_REG, 0); return LinkTestPHY();} /* end EthernetPHYInterruptHandler *//*-------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION:** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**-------------------------------------------------------------------*/UINT16 LinkTestPHY(){ UINT32 j; UINT16 FrameValue = 0; for (j = 0; j < 50; j++) { HAL_DELAY_US(100000); FrameValue = MdioFrame(READ,0,CHIP_STAT_REG,0); if ( (FrameValue & 0x0200) != 0 ) break; } FrameValue &= 0x3800; switch (FrameValue) { case 0x3800: return HUNDRED_FD; case 0x2800: return HUNDRED_HD; case 0x3000: return TEN_FD; case 0x2000: return TEN_HD; default: return NOTLINKED; }}/*-------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION:** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**-------------------------------------------------------------------*/void EnablePHYinterrupt(UINT8 enable){ MdioFrame(WRITE, 0, INT_EN_REG, enable?0x2:0x0);}/*----------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION: generic READ/WRITE function of LXT970 * through the MDC/MDIO interface.** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**---------------------------------------------------------------------*/UINT16 MdioFrame(MDIORW R_W, UINT16 PhyAddr, UINT16 RegAddr, UINT32 PutData) { UINT16 GetData; *pPortDir |= MDIO_PIN_MASK; //set to output mode MdioSend(0xFFFFFFFF,32); //PreAmble MdioSend(0x1,2); //Start Frame Delimiter if (R_W==READ) MdioSend(0x2,2); //Read OpCode else MdioSend(0x1,2); //Write OpCode MdioSend(PhyAddr,5); //Send PHY transciever Address MdioSend(RegAddr,5); //Send Register Address if (R_W==READ) { *pPortDir &= ~MDIO_PIN_MASK; //set to input mode GetData = MdioReceive(17); //Drive TurnAround and Data MdioReceive(2); } else { MdioSend(0x2,2); //Drive TurnAround MdioSend(PutData, 16); //Send Data GetData = 0; *pPortDir &= ~MDIO_PIN_MASK; //set to input mode } return GetData;}/*----------------------------------------------------------------------** FUNCTION NAME: ** DESCRIPTION: Shift out bits of data** EXTERNAL EFFECT:** PARAMETERS:** RETURNS: None** ASSUMPTIONS:**----------------------------------------------------------------------*/void MdioSend(UINT32 txF, UINT16 size) { UINT32 dmask; INT_NATIVE i, j; dmask = 1 << (size-1); // msbit out first for (i = 0; i < size; i++) { // for "size" bits if ( txF & dmask ) //output data bit high *pPortData |= MDIO_PIN_MASK; else //output data bit low > 400ns *pPortData &= ~MDIO_PIN_MASK; // >10ns *pPortData |= MDC_PIN_MASK; // clock rise txF = (UINT32)(txF << 1); // >160ns for (j=0; j<MDC_HOLD_TIME; j++); *pPortData &= ~MDC_PIN_MASK; // clock fall for (j=0; j<MDC_HOLD_TIME; j++); } return;} /*---------------------------------------------------------------------** FUNCTION NAME:** DESCRIPTION: Shifts in bits of data** EXTERNAL EFFECT:** PARAMETERS:** RETURNS:** ASSUMPTIONS:**---------------------------------------------------------------------*/UINT16 MdioReceive(UINT16 size) { UINT16 i,j, rxF = 0; for (i = 0; i < size; i++) { // 16 bits *pPortData |= MDC_PIN_MASK; // clock rise if ( *pPortData & MDIO_PIN_MASK ) // if read in a high bit rxF = ( (UINT16)(rxF << 1) | 1 ); // shift in a one else // if read in a low bit rxF = ( (UINT16)(rxF << 1) & ~(UINT16)1 ); // shift in a zero for (j=0; j<MDC_HOLD_TIME; j++); *pPortData &= ~MDC_PIN_MASK; // clock fall for (j=0; j<MDC_HOLD_TIME; j++); } return rxF;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?