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 <iorx62n.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 /* Get the link partner response */
\r
179 reg = (int16_t)_phy_read(AN_LINK_PARTNER_ABILITY_REG);
\r
181 if (reg & ( 1 << 8 ) )
\r
183 return PHY_LINK_100F;
\r
185 if (reg & ( 1 << 7 ) )
\r
187 return PHY_LINK_100H;
\r
189 if (reg & ( 1 << 6 ) )
\r
191 return PHY_LINK_10F;
\r
195 return PHY_LINK_10H;
\r
204 * Internal functions
\r
207 /******************************************************************************
\r
208 * Function Name: _phy_read
\r
209 * Description : Reads a PHY register
\r
210 * Arguments : reg_addr - address of the PHY register
\r
211 * Return Value : read value
\r
212 ******************************************************************************/
\r
213 uint16_t _phy_read( uint16_t reg_addr )
\r
218 _phy_reg_set( reg_addr, PHY_READ );
\r
220 _phy_reg_read( &data );
\r
226 /******************************************************************************
\r
227 * Function Name: _phy_write
\r
228 * Description : Writes to a PHY register
\r
229 * Arguments : reg_addr - address of the PHY register
\r
231 * Return Value : none
\r
232 ******************************************************************************/
\r
233 void _phy_write( uint16_t reg_addr, uint16_t data )
\r
236 _phy_reg_set( reg_addr, PHY_WRITE );
\r
238 _phy_reg_write( data );
\r
242 /******************************************************************************
\r
243 * Function Name: _phy_preamble
\r
244 * Description : As preliminary preparation for access to the PHY module register,
\r
245 * "1" is output via the MII management interface.
\r
247 * Return Value : none
\r
248 ******************************************************************************/
\r
249 void _phy_preamble( void )
\r
256 _phy_mii_write_1();
\r
261 /******************************************************************************
\r
262 * Function Name: _phy_reg_set
\r
263 * Description : Sets a PHY device to read or write mode
\r
264 * Arguments : reg_addr - address of the PHY register
\r
266 * Return Value : none
\r
267 ******************************************************************************/
\r
268 void _phy_reg_set( uint16_t reg_addr, int32_t option )
\r
274 data = (PHY_ST << 14); /* ST code */
\r
276 if( option == PHY_READ )
\r
278 data |= (PHY_READ << 12); /* OP code(RD) */
\r
282 data |= (PHY_WRITE << 12); /* OP code(WT) */
\r
285 data |= (PHY_ADDR << 7); /* PHY Address */
\r
286 data |= (reg_addr << 2); /* Reg Address */
\r
291 if( (data & 0x8000) == 0 )
\r
293 _phy_mii_write_0();
\r
297 _phy_mii_write_1();
\r
304 /******************************************************************************
\r
305 * Function Name: _phy_reg_read
\r
306 * Description : Reads PHY register through MII interface
\r
307 * Arguments : data - pointer to store the data read
\r
308 * Return Value : none
\r
309 ******************************************************************************/
\r
310 void _phy_reg_read( uint16_t *data )
\r
319 for(j = MDC_WAIT; j > 0; j--)
\r
321 ETHERC.PIR.LONG = 0x00000000;
\r
323 for(j = MDC_WAIT; j > 0; j--)
\r
325 ETHERC.PIR.LONG = 0x00000001;
\r
329 reg_data |= (uint16_t)((ETHERC.PIR.LONG & 0x00000008) >> 3); /* MDI read */
\r
331 for(j = MDC_WAIT; j > 0; j--)
\r
333 ETHERC.PIR.LONG = 0x00000001;
\r
335 for(j = MDC_WAIT; j > 0; j--)
\r
337 ETHERC.PIR.LONG = 0x00000000;
\r
344 /******************************************************************************
\r
345 * Function Name: _phy_reg_write
\r
346 * Description : Writes to PHY register through MII interface
\r
347 * Arguments : data - value to write
\r
348 * Return Value : none
\r
349 ******************************************************************************/
\r
350 void _phy_reg_write( uint16_t data )
\r
357 if( (data & 0x8000) == 0 )
\r
359 _phy_mii_write_0();
\r
363 _phy_mii_write_1();
\r
370 /******************************************************************************
\r
371 * Function Name: _phy_ta_z0
\r
372 * Description : Performs bus release so that PHY can drive data
\r
373 * : for read operation
\r
375 * Return Value : none
\r
376 ******************************************************************************/
\r
377 void _phy_ta_z0( void )
\r
381 for(j = MDC_WAIT; j > 0; j--)
\r
383 ETHERC.PIR.LONG = 0x00000000;
\r
385 for(j = MDC_WAIT; j > 0; j--)
\r
387 ETHERC.PIR.LONG = 0x00000001;
\r
389 for(j = MDC_WAIT; j > 0; j--)
\r
391 ETHERC.PIR.LONG = 0x00000001;
\r
393 for(j = MDC_WAIT; j > 0; j--)
\r
395 ETHERC.PIR.LONG = 0x00000000;
\r
399 /******************************************************************************
\r
400 * Function Name: _phy_ta_10
\r
401 * Description : Switches data bus so MII interface can drive data
\r
402 * : for write operation
\r
404 * Return Value : none
\r
405 ******************************************************************************/
\r
406 void _phy_ta_10(void)
\r
408 _phy_mii_write_1();
\r
409 _phy_mii_write_0();
\r
412 /******************************************************************************
\r
413 * Function Name: _phy_mii_write_1
\r
414 * Description : Outputs 1 to the MII interface
\r
416 * Return Value : none
\r
417 ******************************************************************************/
\r
418 void _phy_mii_write_1( void )
\r
422 for(j = MDC_WAIT; j > 0; j--)
\r
424 ETHERC.PIR.LONG = 0x00000006;
\r
426 for(j = MDC_WAIT; j > 0; j--)
\r
428 ETHERC.PIR.LONG = 0x00000007;
\r
430 for(j = MDC_WAIT; j > 0; j--)
\r
432 ETHERC.PIR.LONG = 0x00000007;
\r
434 for(j = MDC_WAIT; j > 0; j--)
\r
436 ETHERC.PIR.LONG = 0x00000006;
\r
440 /******************************************************************************
\r
441 * Function Name: _phy_mii_write_0
\r
442 * Description : Outputs 0 to the MII interface
\r
444 * Return Value : none
\r
445 ******************************************************************************/
\r
446 void _phy_mii_write_0( void )
\r
450 for(j = MDC_WAIT; j > 0; j--)
\r
452 ETHERC.PIR.LONG = 0x00000002;
\r
454 for(j = MDC_WAIT; j > 0; j--)
\r
456 ETHERC.PIR.LONG = 0x00000003;
\r
458 for(j = MDC_WAIT; j > 0; j--)
\r
460 ETHERC.PIR.LONG = 0x00000003;
\r
462 for(j = MDC_WAIT; j > 0; j--)
\r
464 ETHERC.PIR.LONG = 0x00000002;
\r