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
163 } while (!(reg & 0x0020) && (count < PHY_AUTO_NEGOTIATON_WAIT));
\r
165 if (count >= PHY_AUTO_NEGOTIATON_WAIT)
\r
167 return R_PHY_ERROR;
\r
171 /* National DP83640 fix */
\r
172 _phy_write(0x13, 0x0006);
\r
173 reg = _phy_read(0x14);
\r
174 _phy_write(0x14, (reg&0x7FFF));
\r
175 _phy_write(0x13, 0x0000);
\r
177 /* Get the link partner response */
\r
178 reg = (int16_t)_phy_read(AN_LINK_PARTNER_ABILITY_REG);
\r
180 if (reg & ( 1 << 8 ) )
\r
182 return PHY_LINK_100F;
\r
184 if (reg & ( 1 << 7 ) )
\r
186 return PHY_LINK_100H;
\r
188 if (reg & ( 1 << 6 ) )
\r
190 return PHY_LINK_10F;
\r
194 return PHY_LINK_10H;
\r
203 * Internal functions
\r
206 /******************************************************************************
\r
207 * Function Name: _phy_read
\r
208 * Description : Reads a PHY register
\r
209 * Arguments : reg_addr - address of the PHY register
\r
210 * Return Value : read value
\r
211 ******************************************************************************/
\r
212 uint16_t _phy_read( uint16_t reg_addr )
\r
217 _phy_reg_set( reg_addr, PHY_READ );
\r
219 _phy_reg_read( &data );
\r
225 /******************************************************************************
\r
226 * Function Name: _phy_write
\r
227 * Description : Writes to a PHY register
\r
228 * Arguments : reg_addr - address of the PHY register
\r
230 * Return Value : none
\r
231 ******************************************************************************/
\r
232 void _phy_write( uint16_t reg_addr, uint16_t data )
\r
235 _phy_reg_set( reg_addr, PHY_WRITE );
\r
237 _phy_reg_write( data );
\r
241 /******************************************************************************
\r
242 * Function Name: _phy_preamble
\r
243 * Description : As preliminary preparation for access to the PHY module register,
\r
244 * "1" is output via the MII management interface.
\r
246 * Return Value : none
\r
247 ******************************************************************************/
\r
248 void _phy_preamble( void )
\r
255 _phy_mii_write_1();
\r
260 /******************************************************************************
\r
261 * Function Name: _phy_reg_set
\r
262 * Description : Sets a PHY device to read or write mode
\r
263 * Arguments : reg_addr - address of the PHY register
\r
265 * Return Value : none
\r
266 ******************************************************************************/
\r
267 void _phy_reg_set( uint16_t reg_addr, int32_t option )
\r
273 data = (PHY_ST << 14); /* ST code */
\r
275 if( option == PHY_READ )
\r
277 data |= (PHY_READ << 12); /* OP code(RD) */
\r
281 data |= (PHY_WRITE << 12); /* OP code(WT) */
\r
284 data |= (PHY_ADDR << 7); /* PHY Address */
\r
285 data |= (reg_addr << 2); /* Reg Address */
\r
290 if( (data & 0x8000) == 0 )
\r
292 _phy_mii_write_0();
\r
296 _phy_mii_write_1();
\r
303 /******************************************************************************
\r
304 * Function Name: _phy_reg_read
\r
305 * Description : Reads PHY register through MII interface
\r
306 * Arguments : data - pointer to store the data read
\r
307 * Return Value : none
\r
308 ******************************************************************************/
\r
309 void _phy_reg_read( uint16_t *data )
\r
318 for(j = MDC_WAIT; j > 0; j--)
\r
320 ETHERC.PIR.LONG = 0x00000000;
\r
322 for(j = MDC_WAIT; j > 0; j--)
\r
324 ETHERC.PIR.LONG = 0x00000001;
\r
328 reg_data |= (uint16_t)((ETHERC.PIR.LONG & 0x00000008) >> 3); /* MDI read */
\r
330 for(j = MDC_WAIT; j > 0; j--)
\r
332 ETHERC.PIR.LONG = 0x00000001;
\r
334 for(j = MDC_WAIT; j > 0; j--)
\r
336 ETHERC.PIR.LONG = 0x00000000;
\r
343 /******************************************************************************
\r
344 * Function Name: _phy_reg_write
\r
345 * Description : Writes to PHY register through MII interface
\r
346 * Arguments : data - value to write
\r
347 * Return Value : none
\r
348 ******************************************************************************/
\r
349 void _phy_reg_write( uint16_t data )
\r
356 if( (data & 0x8000) == 0 )
\r
358 _phy_mii_write_0();
\r
362 _phy_mii_write_1();
\r
369 /******************************************************************************
\r
370 * Function Name: _phy_ta_z0
\r
371 * Description : Performs bus release so that PHY can drive data
\r
372 * : for read operation
\r
374 * Return Value : none
\r
375 ******************************************************************************/
\r
376 void _phy_ta_z0( void )
\r
380 for(j = MDC_WAIT; j > 0; j--)
\r
382 ETHERC.PIR.LONG = 0x00000000;
\r
384 for(j = MDC_WAIT; j > 0; j--)
\r
386 ETHERC.PIR.LONG = 0x00000001;
\r
388 for(j = MDC_WAIT; j > 0; j--)
\r
390 ETHERC.PIR.LONG = 0x00000001;
\r
392 for(j = MDC_WAIT; j > 0; j--)
\r
394 ETHERC.PIR.LONG = 0x00000000;
\r
398 /******************************************************************************
\r
399 * Function Name: _phy_ta_10
\r
400 * Description : Switches data bus so MII interface can drive data
\r
401 * : for write operation
\r
403 * Return Value : none
\r
404 ******************************************************************************/
\r
405 void _phy_ta_10(void)
\r
407 _phy_mii_write_1();
\r
408 _phy_mii_write_0();
\r
411 /******************************************************************************
\r
412 * Function Name: _phy_mii_write_1
\r
413 * Description : Outputs 1 to the MII interface
\r
415 * Return Value : none
\r
416 ******************************************************************************/
\r
417 void _phy_mii_write_1( void )
\r
421 for(j = MDC_WAIT; j > 0; j--)
\r
423 ETHERC.PIR.LONG = 0x00000006;
\r
425 for(j = MDC_WAIT; j > 0; j--)
\r
427 ETHERC.PIR.LONG = 0x00000007;
\r
429 for(j = MDC_WAIT; j > 0; j--)
\r
431 ETHERC.PIR.LONG = 0x00000007;
\r
433 for(j = MDC_WAIT; j > 0; j--)
\r
435 ETHERC.PIR.LONG = 0x00000006;
\r
439 /******************************************************************************
\r
440 * Function Name: _phy_mii_write_0
\r
441 * Description : Outputs 0 to the MII interface
\r
443 * Return Value : none
\r
444 ******************************************************************************/
\r
445 void _phy_mii_write_0( void )
\r
449 for(j = MDC_WAIT; j > 0; j--)
\r
451 ETHERC.PIR.LONG = 0x00000002;
\r
453 for(j = MDC_WAIT; j > 0; j--)
\r
455 ETHERC.PIR.LONG = 0x00000003;
\r
457 for(j = MDC_WAIT; j > 0; j--)
\r
459 ETHERC.PIR.LONG = 0x00000003;
\r
461 for(j = MDC_WAIT; j > 0; j--)
\r
463 ETHERC.PIR.LONG = 0x00000002;
\r