| /****************************************************************************** | |
| * File Name : hwEthernetPhy.c | |
| * Version : 1.0 | |
| * Device(s) : Renesas | |
| * Tool-Chain : Renesas SH2A V9+ | |
| * OS : None | |
| * H/W Platform : SH2A | |
| * Description : Hardware driver for the LAN8700 PHY | |
| ******************************************************************************* | |
| * History : DD.MM.YYYY Ver. Description | |
| * : 01.08.2009 1.00 MAB First Release | |
| ******************************************************************************/ | |
| /****************************************************************************** | |
| * DISCLAIMER | |
| * This software is supplied by Renesas Technology Corp. and is only | |
| * intended for use with Renesas products. No other uses are authorized. | |
| * This software is owned by Renesas Technology Corp. and is protected under | |
| * all applicable laws, including copyright laws. | |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES | |
| * REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, | |
| * INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| * PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY | |
| * DISCLAIMED. | |
| * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS | |
| * TECHNOLOGY CORP. NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE | |
| * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES | |
| * FOR ANY REASON RELATED TO THE THIS SOFTWARE, EVEN IF RENESAS OR ITS | |
| * AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
| * Renesas reserves the right, without notice, to make changes to this | |
| * software and to discontinue the availability of this software. | |
| * By using this software, you agree to the additional terms and | |
| * conditions found by accessing the following link: | |
| * http://www.renesas.com/disclaimer | |
| ******************************************************************************/ | |
| /* Copyright (C) 2008. Renesas Technology Corp., All Rights Reserved. */ | |
| /* Copyright (C) 2009. Renesas Technology Europe Ltd., All Rights Reserved. */ | |
| /*****************************************************************************/ | |
| /***************************************************************************** | |
| System Includes | |
| ******************************************************************************/ | |
| #include <stdio.h> | |
| /* Header file for sleep() and nop() functions */ | |
| #include <machine.h> | |
| /***************************************************************************** | |
| User Includes | |
| ******************************************************************************/ | |
| /* Defines for I/O registers */ | |
| #include "iodefine.h" | |
| /* rsk7216def.h provides common defines for widely used items. */ | |
| #include "rsk7216def.h" | |
| /* Physical layer functions */ | |
| #include "hwEthernetPhy.h" | |
| #include "Trace.h" | |
| #include "FreeRTOS.h" | |
| #include "task.h" | |
| /***************************************************************************** | |
| Constant Macros | |
| ******************************************************************************/ | |
| /* Preamble */ | |
| #define PHY_ST 0x0001 | |
| /* Operation to be executed on PHY registers */ | |
| #define PHY_READ 0x0002 | |
| #define PHY_WRITE 0x0001 | |
| /* Physical address of PHY device */ | |
| #define PHY_ADDR 0x001F | |
| /* Description of PHY data registers */ | |
| #define PHY_BASIC_MODE_CONTROL 0x0000 | |
| #define PHY_BASIC_MODE_STATUS 0x0001 | |
| #define PHY_IDENTIFIER1 0x0002 | |
| #define PHY_IDENTIFIER2 0x0003 | |
| #define PHY_AN_ADVERTISEMENT 0x0004 | |
| #define PHY_AN_LINK_PARTNER_ABILITY 0x0005 | |
| /* Definitions of some configuration bits */ | |
| #define PHY_RESET 0x8000 | |
| #define PHY_AN_ENABLE 0x1200 | |
| /* Bits for auto negotiation for 100, 10 half and full duplex set */ | |
| #define PHY_AN_10_100_F_H 0xDE1 | |
| /* Link partner ability register bits for establising the result of the | |
| auto negotiation */ | |
| #define PHY_AN_100F BIT_8 | |
| #define PHY_AN_100H BIT_7 | |
| #define PHY_AN_10F BIT_6 | |
| #define PHY_AN_10H BIT_5 | |
| /***************************************************************************** | |
| Function Prototypes | |
| ******************************************************************************/ | |
| static USHORT phyReadReg(USHORT usRegAddr); | |
| static void phyWriteReg(USHORT usRegAddr, USHORT usData); | |
| static void phyPreamble(void); | |
| static void phyMiiWrite1(void); | |
| static void phyMiiWrite0(void); | |
| static void phyRegSet(USHORT usRegAddr, long lOption); | |
| static void phyRegRead(PUSHORT pusData); | |
| static void phyRegWrite(USHORT usData); | |
| static void phyTaZ0(void); | |
| static void phyTa10(void); | |
| static void phyDelay(void); | |
| /***************************************************************************** | |
| Public Functions | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyReset | |
| Description: Executes software reset of PHY and sets to auto negotiate link | |
| Parameters: None | |
| Return value: 0 for success -1 on error | |
| ******************************************************************************/ | |
| int phyReset(void) | |
| { | |
| /* One second of attempting to reset the PHY */ | |
| int iCount = 1000; | |
| /* Set software reset */ | |
| phyWriteReg(PHY_BASIC_MODE_CONTROL, PHY_RESET); | |
| while (iCount--) | |
| { | |
| USHORT usData; | |
| vTaskDelay( 2 / portTICK_PERIOD_MS ); | |
| /* Read the status of the PHY */ | |
| usData = phyReadReg(PHY_BASIC_MODE_CONTROL); | |
| /* Wait for the reset flag to be cleared */ | |
| if ((usData & PHY_RESET) == 0) | |
| { | |
| /* Set auto negoatiation for 10,100 full and half duplex */ | |
| phyWriteReg(PHY_AN_ADVERTISEMENT, PHY_AN_10_100_F_H); | |
| /* Set auto negotiate and restart auto negotiate bits */ | |
| phyWriteReg(PHY_BASIC_MODE_CONTROL, PHY_AN_ENABLE); | |
| /* Auto negotiation will now take place wait for two seconds */ | |
| vTaskDelay( 2000 / portTICK_PERIOD_MS ); | |
| /* Success */ | |
| return 0; | |
| } | |
| } | |
| /* Phy did not respond to software reset */ | |
| return -1; | |
| } | |
| /***************************************************************************** | |
| End of function phyReset | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyStatus | |
| Description: Function to reurn the type of physical link | |
| Parameters: none | |
| Return value: The link type | |
| *****************************************************************************/ | |
| NETLNK phyStatus(void) | |
| { | |
| /* The state of this flag depens on the hardware connection to the MAC */ | |
| if (!EtherC.PSR.BIT.LMON) | |
| { | |
| /* Read the auto negotiation link partner ability register to establish | |
| the type of link */ | |
| USHORT usData = phyReadReg(PHY_AN_LINK_PARTNER_ABILITY); | |
| if (usData & PHY_AN_100F) | |
| { | |
| return PHY_LINK_100F; | |
| } | |
| if (usData & PHY_AN_100H) | |
| { | |
| return PHY_LINK_100H; | |
| } | |
| if (usData & PHY_AN_10F) | |
| { | |
| return PHY_LINK_10F; | |
| } | |
| if (usData & PHY_AN_10H) | |
| { | |
| return PHY_LINK_10H; | |
| } | |
| } | |
| return PHY_NO_LINK; | |
| } | |
| /***************************************************************************** | |
| End of function phyStatus | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Private Functions | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyReadReg | |
| Description: Reads data from a register with the address usRegAddr | |
| Parameters: (USHORT) usRegAddr - address to be read; | |
| Return value: (USHORT) - value from read register; | |
| ******************************************************************************/ | |
| static USHORT phyReadReg(USHORT usRegAddr) | |
| { | |
| USHORT usData; | |
| phyPreamble(); | |
| phyRegSet(usRegAddr, PHY_READ); | |
| phyTaZ0(); | |
| phyRegRead(&usData); | |
| phyTaZ0(); | |
| return usData; | |
| } | |
| /***************************************************************************** | |
| End of function phyReadReg | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyWriteReg | |
| Description: Write data to register with the address usRegAddr | |
| Parameters: (USHORT) usRegAddr - address of register where to be written; | |
| (USHORT) usData - value to write; | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyWriteReg(USHORT usRegAddr, USHORT usData) | |
| { | |
| phyPreamble(); | |
| phyRegSet(usRegAddr, PHY_WRITE); | |
| phyTa10(); | |
| phyRegWrite(usData); | |
| phyTaZ0(); | |
| } | |
| /***************************************************************************** | |
| End of function phyWriteReg | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyPreamble | |
| Description: Writing 32 bits of '1' | |
| Parameters: None | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyPreamble(void) | |
| { | |
| int iCount = 32; | |
| while (iCount--) | |
| { | |
| phyMiiWrite1(); | |
| } | |
| } | |
| /***************************************************************************** | |
| End of function phyPreamble | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyRegSet | |
| Description: Sets the address of register | |
| Parameters: (USHORT) usRegAddr - address to be set; | |
| (long) lOption - PHY_READ or PHY_WRITE; | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyRegSet(USHORT usRegAddr, long lOption) | |
| { | |
| int iBit = 14; | |
| USHORT usData; | |
| /* Format of PHY Address Set Transmission */ | |
| /* ST R/W PAddress Address */ | |
| /* 1 10 11111 xxxx 00 */ //Read | |
| /* 1 01 11111 xxxx 00 */ //Write | |
| usData = 0; | |
| /* ST code */ | |
| usData = (PHY_ST << 14); | |
| if (lOption == PHY_READ) | |
| { | |
| /* Option code (RD) */ | |
| usData |= (PHY_READ << 12); | |
| } | |
| else | |
| { | |
| /* Option code (WT) */ | |
| usData |= (PHY_WRITE << 12); | |
| } | |
| /* PHY Address */ | |
| usData |= ((BYTE)PHY_ADDR << 7); | |
| /* Reg Address */ | |
| usData |= (USHORT)(usRegAddr << 2); | |
| while (iBit--) | |
| { | |
| if ((usData & 0x8000) == 0) | |
| { | |
| phyMiiWrite0(); | |
| } | |
| else | |
| { | |
| phyMiiWrite1(); | |
| } | |
| usData <<= 1; | |
| } | |
| } | |
| /***************************************************************************** | |
| End of function phyRegSet | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyRegRead | |
| Description: Read data from register | |
| Parameters: IN pusDest - value to be read; | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyRegRead(PUSHORT pusDest) | |
| { | |
| USHORT usData = 0; | |
| int iBit = 16; | |
| while (iBit--) | |
| { | |
| EtherC.PIR.LONG = 0x00UL; | |
| EtherC.PIR.LONG = 0x01UL; | |
| usData <<= 1; | |
| /* MDI read */ | |
| usData |= (USHORT)((EtherC.PIR.LONG & 0x08UL) >> 3); | |
| EtherC.PIR.LONG = 0x01UL; | |
| EtherC.PIR.LONG = 0x00UL; | |
| } | |
| *pusDest = usData; | |
| } | |
| /***************************************************************************** | |
| End of function phyRegRead | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyRegWrite | |
| Description: Write 2 bytes (16 bit) to MII | |
| Parameters: IN usData - value to be written; | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyRegWrite(USHORT usData) | |
| { | |
| int iBit = 16; | |
| while (iBit--) | |
| { | |
| if ((usData & 0x8000) == 0) | |
| { | |
| phyMiiWrite0(); | |
| } | |
| else | |
| { | |
| phyMiiWrite1(); | |
| } | |
| usData <<= 1; | |
| } | |
| } | |
| /***************************************************************************** | |
| End of function phyRegWrite | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyTaZ0 | |
| Description: Set bus to high Z | |
| Parameters: None | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyTaZ0(void) | |
| { | |
| EtherC.PIR.LONG = 0x00UL; | |
| EtherC.PIR.LONG = 0x01UL; | |
| EtherC.PIR.LONG = 0x01UL; | |
| EtherC.PIR.LONG = 0x00UL; | |
| } | |
| /***************************************************************************** | |
| End of function phyTaZ0 | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyTa10 | |
| Description: Set bus to output | |
| Parameters: None | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyTa10(void) | |
| { | |
| EtherC.PIR.LONG = 0x06UL; | |
| EtherC.PIR.LONG = 0x07UL; | |
| EtherC.PIR.LONG = 0x07UL; | |
| EtherC.PIR.LONG = 0x06UL; | |
| EtherC.PIR.LONG = 0x02UL; | |
| EtherC.PIR.LONG = 0x03UL; | |
| EtherC.PIR.LONG = 0x03UL; | |
| EtherC.PIR.LONG = 0x02UL; | |
| } | |
| /***************************************************************************** | |
| End of function phyTa10 | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyMiiWrite1 | |
| Description: Write 1 to MII | |
| Parameters: None | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyMiiWrite1(void) | |
| { | |
| EtherC.PIR.LONG = 0x06UL; | |
| EtherC.PIR.LONG = 0x07UL; | |
| EtherC.PIR.LONG = 0x07UL; | |
| EtherC.PIR.LONG = 0x06UL; | |
| } | |
| /***************************************************************************** | |
| End of function phyMiiWrite1 | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| Function Name: phyMiiWrite0 | |
| Description: Write 0 to MII | |
| Parameters: None | |
| Return value: None | |
| ******************************************************************************/ | |
| static void phyMiiWrite0(void) | |
| { | |
| EtherC.PIR.LONG = 0x02UL; | |
| EtherC.PIR.LONG = 0x03UL; | |
| EtherC.PIR.LONG = 0x03UL; | |
| EtherC.PIR.LONG = 0x02UL; | |
| } | |
| /***************************************************************************** | |
| End of function phyMiiWrite0 | |
| ******************************************************************************/ | |
| /***************************************************************************** | |
| End Of File | |
| ******************************************************************************/ |