1 /******************************************************************************
\r
2 * File Name : hwEthernetPhy.c
\r
4 * Device(s) : Renesas
\r
5 * Tool-Chain : Renesas SH2A V9+
\r
7 * H/W Platform : SH2A
\r
8 * Description : Hardware driver for the LAN8700 PHY
\r
9 *******************************************************************************
\r
10 * History : DD.MM.YYYY Ver. Description
\r
11 * : 01.08.2009 1.00 MAB First Release
\r
12 ******************************************************************************/
\r
14 /******************************************************************************
\r
16 * This software is supplied by Renesas Technology Corp. and is only
\r
17 * intended for use with Renesas products. No other uses are authorized.
\r
18 * This software is owned by Renesas Technology Corp. and is protected under
\r
19 * all applicable laws, including copyright laws.
\r
20 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES
\r
21 * REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY,
\r
22 * INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
\r
23 * PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY
\r
25 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
\r
26 * TECHNOLOGY CORP. NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
\r
27 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
\r
28 * FOR ANY REASON RELATED TO THE THIS SOFTWARE, EVEN IF RENESAS OR ITS
\r
29 * AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\r
30 * Renesas reserves the right, without notice, to make changes to this
\r
31 * software and to discontinue the availability of this software.
\r
32 * By using this software, you agree to the additional terms and
\r
33 * conditions found by accessing the following link:
\r
34 * http://www.renesas.com/disclaimer
\r
35 ******************************************************************************/
\r
36 /* Copyright (C) 2008. Renesas Technology Corp., All Rights Reserved. */
\r
37 /* Copyright (C) 2009. Renesas Technology Europe Ltd., All Rights Reserved. */
\r
38 /*****************************************************************************/
\r
40 /*****************************************************************************
\r
42 ******************************************************************************/
\r
45 /* Header file for sleep() and nop() functions */
\r
46 #include <machine.h>
\r
48 /*****************************************************************************
\r
50 ******************************************************************************/
\r
52 /* Defines for I/O registers */
\r
53 #include "iodefine.h"
\r
54 /* rsk7216def.h provides common defines for widely used items. */
\r
55 #include "rsk7216def.h"
\r
56 /* Physical layer functions */
\r
57 #include "hwEthernetPhy.h"
\r
60 #include "FreeRTOS.h"
\r
63 /*****************************************************************************
\r
65 ******************************************************************************/
\r
68 #define PHY_ST 0x0001
\r
69 /* Operation to be executed on PHY registers */
\r
70 #define PHY_READ 0x0002
\r
71 #define PHY_WRITE 0x0001
\r
72 /* Physical address of PHY device */
\r
73 #define PHY_ADDR 0x001F
\r
75 /* Description of PHY data registers */
\r
76 #define PHY_BASIC_MODE_CONTROL 0x0000
\r
77 #define PHY_BASIC_MODE_STATUS 0x0001
\r
78 #define PHY_IDENTIFIER1 0x0002
\r
79 #define PHY_IDENTIFIER2 0x0003
\r
80 #define PHY_AN_ADVERTISEMENT 0x0004
\r
81 #define PHY_AN_LINK_PARTNER_ABILITY 0x0005
\r
83 /* Definitions of some configuration bits */
\r
84 #define PHY_RESET 0x8000
\r
85 #define PHY_AN_ENABLE 0x1200
\r
86 /* Bits for auto negotiation for 100, 10 half and full duplex set */
\r
87 #define PHY_AN_10_100_F_H 0xDE1
\r
88 /* Link partner ability register bits for establising the result of the
\r
90 #define PHY_AN_100F BIT_8
\r
91 #define PHY_AN_100H BIT_7
\r
92 #define PHY_AN_10F BIT_6
\r
93 #define PHY_AN_10H BIT_5
\r
95 /*****************************************************************************
\r
97 ******************************************************************************/
\r
99 static USHORT phyReadReg(USHORT usRegAddr);
\r
100 static void phyWriteReg(USHORT usRegAddr, USHORT usData);
\r
101 static void phyPreamble(void);
\r
102 static void phyMiiWrite1(void);
\r
103 static void phyMiiWrite0(void);
\r
104 static void phyRegSet(USHORT usRegAddr, long lOption);
\r
105 static void phyRegRead(PUSHORT pusData);
\r
106 static void phyRegWrite(USHORT usData);
\r
107 static void phyTaZ0(void);
\r
108 static void phyTa10(void);
\r
109 static void phyDelay(void);
\r
111 /*****************************************************************************
\r
113 ******************************************************************************/
\r
115 /*****************************************************************************
\r
116 Function Name: phyReset
\r
117 Description: Executes software reset of PHY and sets to auto negotiate link
\r
119 Return value: 0 for success -1 on error
\r
120 ******************************************************************************/
\r
123 /* One second of attempting to reset the PHY */
\r
124 int iCount = 1000;
\r
125 /* Set software reset */
\r
126 phyWriteReg(PHY_BASIC_MODE_CONTROL, PHY_RESET);
\r
131 vTaskDelay( 2 / portTICK_PERIOD_MS );
\r
133 /* Read the status of the PHY */
\r
134 usData = phyReadReg(PHY_BASIC_MODE_CONTROL);
\r
135 /* Wait for the reset flag to be cleared */
\r
136 if ((usData & PHY_RESET) == 0)
\r
138 /* Set auto negoatiation for 10,100 full and half duplex */
\r
139 phyWriteReg(PHY_AN_ADVERTISEMENT, PHY_AN_10_100_F_H);
\r
140 /* Set auto negotiate and restart auto negotiate bits */
\r
141 phyWriteReg(PHY_BASIC_MODE_CONTROL, PHY_AN_ENABLE);
\r
143 /* Auto negotiation will now take place wait for two seconds */
\r
144 vTaskDelay( 2000 / portTICK_PERIOD_MS );
\r
150 /* Phy did not respond to software reset */
\r
153 /*****************************************************************************
\r
154 End of function phyReset
\r
155 ******************************************************************************/
\r
157 /*****************************************************************************
\r
158 Function Name: phyStatus
\r
159 Description: Function to reurn the type of physical link
\r
161 Return value: The link type
\r
162 *****************************************************************************/
\r
163 NETLNK phyStatus(void)
\r
165 /* The state of this flag depens on the hardware connection to the MAC */
\r
166 if (!EtherC.PSR.BIT.LMON)
\r
168 /* Read the auto negotiation link partner ability register to establish
\r
169 the type of link */
\r
170 USHORT usData = phyReadReg(PHY_AN_LINK_PARTNER_ABILITY);
\r
171 if (usData & PHY_AN_100F)
\r
173 return PHY_LINK_100F;
\r
175 if (usData & PHY_AN_100H)
\r
177 return PHY_LINK_100H;
\r
179 if (usData & PHY_AN_10F)
\r
181 return PHY_LINK_10F;
\r
183 if (usData & PHY_AN_10H)
\r
185 return PHY_LINK_10H;
\r
188 return PHY_NO_LINK;
\r
190 /*****************************************************************************
\r
191 End of function phyStatus
\r
192 ******************************************************************************/
\r
194 /*****************************************************************************
\r
196 ******************************************************************************/
\r
198 /*****************************************************************************
\r
199 Function Name: phyReadReg
\r
200 Description: Reads data from a register with the address usRegAddr
\r
201 Parameters: (USHORT) usRegAddr - address to be read;
\r
202 Return value: (USHORT) - value from read register;
\r
203 ******************************************************************************/
\r
204 static USHORT phyReadReg(USHORT usRegAddr)
\r
208 phyRegSet(usRegAddr, PHY_READ);
\r
210 phyRegRead(&usData);
\r
214 /*****************************************************************************
\r
215 End of function phyReadReg
\r
216 ******************************************************************************/
\r
218 /*****************************************************************************
\r
219 Function Name: phyWriteReg
\r
220 Description: Write data to register with the address usRegAddr
\r
221 Parameters: (USHORT) usRegAddr - address of register where to be written;
\r
222 (USHORT) usData - value to write;
\r
224 ******************************************************************************/
\r
225 static void phyWriteReg(USHORT usRegAddr, USHORT usData)
\r
228 phyRegSet(usRegAddr, PHY_WRITE);
\r
230 phyRegWrite(usData);
\r
233 /*****************************************************************************
\r
234 End of function phyWriteReg
\r
235 ******************************************************************************/
\r
237 /*****************************************************************************
\r
238 Function Name: phyPreamble
\r
239 Description: Writing 32 bits of '1'
\r
242 ******************************************************************************/
\r
243 static void phyPreamble(void)
\r
251 /*****************************************************************************
\r
252 End of function phyPreamble
\r
253 ******************************************************************************/
\r
255 /*****************************************************************************
\r
256 Function Name: phyRegSet
\r
257 Description: Sets the address of register
\r
258 Parameters: (USHORT) usRegAddr - address to be set;
\r
259 (long) lOption - PHY_READ or PHY_WRITE;
\r
261 ******************************************************************************/
\r
262 static void phyRegSet(USHORT usRegAddr, long lOption)
\r
267 /* Format of PHY Address Set Transmission */
\r
268 /* ST R/W PAddress Address */
\r
269 /* 1 10 11111 xxxx 00 */ //Read
\r
270 /* 1 01 11111 xxxx 00 */ //Write
\r
274 usData = (PHY_ST << 14);
\r
275 if (lOption == PHY_READ)
\r
277 /* Option code (RD) */
\r
278 usData |= (PHY_READ << 12);
\r
282 /* Option code (WT) */
\r
283 usData |= (PHY_WRITE << 12);
\r
286 usData |= ((BYTE)PHY_ADDR << 7);
\r
288 usData |= (USHORT)(usRegAddr << 2);
\r
292 if ((usData & 0x8000) == 0)
\r
303 /*****************************************************************************
\r
304 End of function phyRegSet
\r
305 ******************************************************************************/
\r
307 /*****************************************************************************
\r
308 Function Name: phyRegRead
\r
309 Description: Read data from register
\r
310 Parameters: IN pusDest - value to be read;
\r
312 ******************************************************************************/
\r
313 static void phyRegRead(PUSHORT pusDest)
\r
319 EtherC.PIR.LONG = 0x00UL;
\r
320 EtherC.PIR.LONG = 0x01UL;
\r
324 usData |= (USHORT)((EtherC.PIR.LONG & 0x08UL) >> 3);
\r
326 EtherC.PIR.LONG = 0x01UL;
\r
327 EtherC.PIR.LONG = 0x00UL;
\r
331 /*****************************************************************************
\r
332 End of function phyRegRead
\r
333 ******************************************************************************/
\r
335 /*****************************************************************************
\r
336 Function Name: phyRegWrite
\r
337 Description: Write 2 bytes (16 bit) to MII
\r
338 Parameters: IN usData - value to be written;
\r
340 ******************************************************************************/
\r
341 static void phyRegWrite(USHORT usData)
\r
346 if ((usData & 0x8000) == 0)
\r
357 /*****************************************************************************
\r
358 End of function phyRegWrite
\r
359 ******************************************************************************/
\r
361 /*****************************************************************************
\r
362 Function Name: phyTaZ0
\r
363 Description: Set bus to high Z
\r
366 ******************************************************************************/
\r
367 static void phyTaZ0(void)
\r
369 EtherC.PIR.LONG = 0x00UL;
\r
370 EtherC.PIR.LONG = 0x01UL;
\r
371 EtherC.PIR.LONG = 0x01UL;
\r
372 EtherC.PIR.LONG = 0x00UL;
\r
374 /*****************************************************************************
\r
375 End of function phyTaZ0
\r
376 ******************************************************************************/
\r
378 /*****************************************************************************
\r
379 Function Name: phyTa10
\r
380 Description: Set bus to output
\r
383 ******************************************************************************/
\r
384 static void phyTa10(void)
\r
386 EtherC.PIR.LONG = 0x06UL;
\r
387 EtherC.PIR.LONG = 0x07UL;
\r
388 EtherC.PIR.LONG = 0x07UL;
\r
389 EtherC.PIR.LONG = 0x06UL;
\r
390 EtherC.PIR.LONG = 0x02UL;
\r
391 EtherC.PIR.LONG = 0x03UL;
\r
392 EtherC.PIR.LONG = 0x03UL;
\r
393 EtherC.PIR.LONG = 0x02UL;
\r
395 /*****************************************************************************
\r
396 End of function phyTa10
\r
397 ******************************************************************************/
\r
399 /*****************************************************************************
\r
400 Function Name: phyMiiWrite1
\r
401 Description: Write 1 to MII
\r
404 ******************************************************************************/
\r
405 static void phyMiiWrite1(void)
\r
407 EtherC.PIR.LONG = 0x06UL;
\r
408 EtherC.PIR.LONG = 0x07UL;
\r
409 EtherC.PIR.LONG = 0x07UL;
\r
410 EtherC.PIR.LONG = 0x06UL;
\r
412 /*****************************************************************************
\r
413 End of function phyMiiWrite1
\r
414 ******************************************************************************/
\r
416 /*****************************************************************************
\r
417 Function Name: phyMiiWrite0
\r
418 Description: Write 0 to MII
\r
421 ******************************************************************************/
\r
422 static void phyMiiWrite0(void)
\r
424 EtherC.PIR.LONG = 0x02UL;
\r
425 EtherC.PIR.LONG = 0x03UL;
\r
426 EtherC.PIR.LONG = 0x03UL;
\r
427 EtherC.PIR.LONG = 0x02UL;
\r
429 /*****************************************************************************
\r
430 End of function phyMiiWrite0
\r
431 ******************************************************************************/
\r
433 /*****************************************************************************
\r
435 ******************************************************************************/
\r