1 /******************************************************************************
\r
4 * This software is supplied by Renesas Technology Corp. and is only
\r
5 * intended for use with Renesas products. No other uses are authorized.
\r
7 * This software is owned by Renesas Technology Corp. and is protected under
\r
8 * all applicable laws, including copyright laws.
\r
10 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES
\r
11 * REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY,
\r
12 * INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
\r
13 * PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY
\r
16 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
\r
17 * TECHNOLOGY CORP. NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
\r
18 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
\r
19 * FOR ANY REASON RELATED TO THE THIS SOFTWARE, EVEN IF RENESAS OR ITS
\r
20 * AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\r
22 * Renesas reserves the right, without notice, to make changes to this
\r
23 * software and to discontinue the availability of this software.
\r
24 * By using this software, you agree to the additional terms and
\r
25 * conditions found by accessing the following link:
\r
26 * http://www.renesas.com/disclaimer
\r
27 ******************************************************************************
\r
28 * Copyright (C) 2008. Renesas Technology Corp., All Rights Reserved.
\r
29 *******************************************************************************
\r
32 * Description : Ethernet PHY device driver
\r
33 ******************************************************************************
\r
34 * History : DD.MM.YYYY Version Description
\r
35 * : 15.02.2010 1.00 First Release
\r
36 * : 06.04.2010 1.01 RX62N changes
\r
37 ******************************************************************************/
\r
40 /******************************************************************************
\r
41 Includes <System Includes> , "Project Includes"
\r
42 ******************************************************************************/
\r
43 #include "iodefine.h"
\r
44 #include "r_ether.h"
\r
47 #include "FreeRTOS.h"
\r
49 /******************************************************************************
\r
51 ******************************************************************************/
\r
53 /******************************************************************************
\r
55 ******************************************************************************/
\r
57 /******************************************************************************
\r
58 Imported global variables and functions (from other files)
\r
59 ******************************************************************************/
\r
61 /******************************************************************************
\r
62 Exported global variables and functions (to be accessed by other files)
\r
63 ******************************************************************************/
\r
65 /******************************************************************************
\r
66 Private global variables and functions
\r
67 ******************************************************************************/
\r
68 uint16_t _phy_read( uint16_t reg_addr );
\r
69 void _phy_write( uint16_t reg_addr, uint16_t data );
\r
70 void _phy_preamble( void );
\r
71 void _phy_reg_set( uint16_t reg_addr, int32_t option );
\r
72 void _phy_reg_read( uint16_t *data );
\r
73 void _phy_reg_write( uint16_t data );
\r
74 void _phy_ta_z0( void );
\r
75 void _phy_ta_10( void );
\r
76 void _phy_mii_write_1( void );
\r
77 void _phy_mii_write_0( void );
\r
80 * External functions
\r
83 /******************************************************************************
\r
84 * Function Name: phy_init
\r
85 * Description : Resets Ethernet PHY device
\r
87 * Return Value : none
\r
88 ******************************************************************************/
\r
89 int16_t phy_init( void )
\r
95 _phy_write(BASIC_MODE_CONTROL_REG, 0x8000);
\r
101 vTaskDelay( 2 / portTICK_RATE_MS );
\r
102 reg = _phy_read(BASIC_MODE_CONTROL_REG);
\r
104 } while (reg & 0x8000 && count < PHY_RESET_WAIT);
\r
106 if( count < PHY_RESET_WAIT )
\r
111 return R_PHY_ERROR;
\r
114 /******************************************************************************
\r
115 * Function Name: phy_set_100full
\r
116 * Description : Set Ethernet PHY device to 100 Mbps full duplex
\r
118 * Return Value : none
\r
119 ******************************************************************************/
\r
120 void phy_set_100full( void )
\r
122 _phy_write(BASIC_MODE_CONTROL_REG, 0x2100);
\r
125 /******************************************************************************
\r
126 * Function Name: phy_set_10half
\r
127 * Description : Sets Ethernet PHY device to 10 Mbps half duplexR
\r
129 * Return Value : none
\r
130 ******************************************************************************/
\r
131 void phy_set_10half( void )
\r
133 _phy_write(BASIC_MODE_CONTROL_REG, 0x0000);
\r
136 /******************************************************************************
\r
137 * Function Name: phy_set_autonegotiate
\r
138 * Description : Starts autonegotiate and reports the other side's
\r
139 * : physical capability
\r
141 * Return Value : bit 8 - Full duplex 100 mbps
\r
142 * : bit 7 - Half duplex 100 mbps
\r
143 * : bit 6 - Full duplex 10 mbps
\r
144 * : bit 5 - Half duplex 10 mbps
\r
145 * : bit 4:0 - Always set to 00001 (IEEE 802.3)
\r
147 ******************************************************************************/
\r
148 int16_t phy_set_autonegotiate( void )
\r
153 _phy_write(AN_ADVERTISEMENT_REG, 0x01E1);
\r
154 _phy_write(BASIC_MODE_CONTROL_REG, 0x1200);
\r
160 reg = _phy_read(BASIC_MODE_STATUS_REG);
\r
162 vTaskDelay( 100 / portTICK_RATE_MS );
\r
164 /* Make sure we don't break out if reg just contains 0xffff. */
\r
165 if( reg == 0xffff )
\r
170 } while (!(reg & 0x0020) && (count < PHY_AUTO_NEGOTIATON_WAIT));
\r
172 if (count >= PHY_AUTO_NEGOTIATON_WAIT)
\r
174 return R_PHY_ERROR;
\r
178 /* National DP83640 fix */
\r
179 _phy_write(0x13, 0x0006);
\r
180 reg = _phy_read(0x14);
\r
181 _phy_write(0x14, (reg&0x7FFF));
\r
182 _phy_write(0x13, 0x0000);
\r
184 /* Get the link partner response */
\r
185 reg = (int16_t)_phy_read(AN_LINK_PARTNER_ABILITY_REG);
\r
187 if (reg & ( 1 << 8 ) )
\r
189 return PHY_LINK_100F;
\r
191 if (reg & ( 1 << 7 ) )
\r
193 return PHY_LINK_100H;
\r
195 if (reg & ( 1 << 6 ) )
\r
197 return PHY_LINK_10F;
\r
201 return PHY_LINK_10H;
\r
210 * Internal functions
\r
213 /******************************************************************************
\r
214 * Function Name: _phy_read
\r
215 * Description : Reads a PHY register
\r
216 * Arguments : reg_addr - address of the PHY register
\r
217 * Return Value : read value
\r
218 ******************************************************************************/
\r
219 uint16_t _phy_read( uint16_t reg_addr )
\r
224 _phy_reg_set( reg_addr, PHY_READ );
\r
226 _phy_reg_read( &data );
\r
232 /******************************************************************************
\r
233 * Function Name: _phy_write
\r
234 * Description : Writes to a PHY register
\r
235 * Arguments : reg_addr - address of the PHY register
\r
237 * Return Value : none
\r
238 ******************************************************************************/
\r
239 void _phy_write( uint16_t reg_addr, uint16_t data )
\r
242 _phy_reg_set( reg_addr, PHY_WRITE );
\r
244 _phy_reg_write( data );
\r
248 /******************************************************************************
\r
249 * Function Name: _phy_preamble
\r
250 * Description : As preliminary preparation for access to the PHY module register,
\r
251 * "1" is output via the MII management interface.
\r
253 * Return Value : none
\r
254 ******************************************************************************/
\r
255 void _phy_preamble( void )
\r
262 _phy_mii_write_1();
\r
267 /******************************************************************************
\r
268 * Function Name: _phy_reg_set
\r
269 * Description : Sets a PHY device to read or write mode
\r
270 * Arguments : reg_addr - address of the PHY register
\r
272 * Return Value : none
\r
273 ******************************************************************************/
\r
274 void _phy_reg_set( uint16_t reg_addr, int32_t option )
\r
280 data = (PHY_ST << 14); /* ST code */
\r
282 if( option == PHY_READ )
\r
284 data |= (PHY_READ << 12); /* OP code(RD) */
\r
288 data |= (PHY_WRITE << 12); /* OP code(WT) */
\r
291 data |= (PHY_ADDR << 7); /* PHY Address */
\r
292 data |= (reg_addr << 2); /* Reg Address */
\r
297 if( (data & 0x8000) == 0 )
\r
299 _phy_mii_write_0();
\r
303 _phy_mii_write_1();
\r
310 /******************************************************************************
\r
311 * Function Name: _phy_reg_read
\r
312 * Description : Reads PHY register through MII interface
\r
313 * Arguments : data - pointer to store the data read
\r
314 * Return Value : none
\r
315 ******************************************************************************/
\r
316 void _phy_reg_read( uint16_t *data )
\r
325 for(j = MDC_WAIT; j > 0; j--)
\r
327 ETHERC.PIR.LONG = 0x00000000;
\r
329 for(j = MDC_WAIT; j > 0; j--)
\r
331 ETHERC.PIR.LONG = 0x00000001;
\r
335 reg_data |= (uint16_t)((ETHERC.PIR.LONG & 0x00000008) >> 3); /* MDI read */
\r
337 for(j = MDC_WAIT; j > 0; j--)
\r
339 ETHERC.PIR.LONG = 0x00000001;
\r
341 for(j = MDC_WAIT; j > 0; j--)
\r
343 ETHERC.PIR.LONG = 0x00000000;
\r
350 /******************************************************************************
\r
351 * Function Name: _phy_reg_write
\r
352 * Description : Writes to PHY register through MII interface
\r
353 * Arguments : data - value to write
\r
354 * Return Value : none
\r
355 ******************************************************************************/
\r
356 void _phy_reg_write( uint16_t data )
\r
363 if( (data & 0x8000) == 0 )
\r
365 _phy_mii_write_0();
\r
369 _phy_mii_write_1();
\r
376 /******************************************************************************
\r
377 * Function Name: _phy_ta_z0
\r
378 * Description : Performs bus release so that PHY can drive data
\r
379 * : for read operation
\r
381 * Return Value : none
\r
382 ******************************************************************************/
\r
383 void _phy_ta_z0( void )
\r
387 for(j = MDC_WAIT; j > 0; j--)
\r
389 ETHERC.PIR.LONG = 0x00000000;
\r
391 for(j = MDC_WAIT; j > 0; j--)
\r
393 ETHERC.PIR.LONG = 0x00000001;
\r
395 for(j = MDC_WAIT; j > 0; j--)
\r
397 ETHERC.PIR.LONG = 0x00000001;
\r
399 for(j = MDC_WAIT; j > 0; j--)
\r
401 ETHERC.PIR.LONG = 0x00000000;
\r
405 /******************************************************************************
\r
406 * Function Name: _phy_ta_10
\r
407 * Description : Switches data bus so MII interface can drive data
\r
408 * : for write operation
\r
410 * Return Value : none
\r
411 ******************************************************************************/
\r
412 void _phy_ta_10(void)
\r
414 _phy_mii_write_1();
\r
415 _phy_mii_write_0();
\r
418 /******************************************************************************
\r
419 * Function Name: _phy_mii_write_1
\r
420 * Description : Outputs 1 to the MII interface
\r
422 * Return Value : none
\r
423 ******************************************************************************/
\r
424 void _phy_mii_write_1( void )
\r
428 for(j = MDC_WAIT; j > 0; j--)
\r
430 ETHERC.PIR.LONG = 0x00000006;
\r
432 for(j = MDC_WAIT; j > 0; j--)
\r
434 ETHERC.PIR.LONG = 0x00000007;
\r
436 for(j = MDC_WAIT; j > 0; j--)
\r
438 ETHERC.PIR.LONG = 0x00000007;
\r
440 for(j = MDC_WAIT; j > 0; j--)
\r
442 ETHERC.PIR.LONG = 0x00000006;
\r
446 /******************************************************************************
\r
447 * Function Name: _phy_mii_write_0
\r
448 * Description : Outputs 0 to the MII interface
\r
450 * Return Value : none
\r
451 ******************************************************************************/
\r
452 void _phy_mii_write_0( void )
\r
456 for(j = MDC_WAIT; j > 0; j--)
\r
458 ETHERC.PIR.LONG = 0x00000002;
\r
460 for(j = MDC_WAIT; j > 0; j--)
\r
462 ETHERC.PIR.LONG = 0x00000003;
\r
464 for(j = MDC_WAIT; j > 0; j--)
\r
466 ETHERC.PIR.LONG = 0x00000003;
\r
468 for(j = MDC_WAIT; j > 0; j--)
\r
470 ETHERC.PIR.LONG = 0x00000002;
\r