]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / CORTEX_Kinetis_K60_Tower_IAR / Freescale_Code / drivers / enet / mii.c
1 /*!\r
2  * \file    mii.c\r
3  * \brief   Media Independent Interface (MII) driver\r
4  * \version $Revision: 1.2 $\r
5  * \author  Michael Norman\r
6  * \r
7  * \warning This driver assumes that FEC0 is used for all MII management\r
8  *          communications. For dual PHYs, etc. Insure that FEC0_MDC and\r
9  *          FEC0_MDIO are connected to the PHY's MDC and MDIO.\r
10  */\r
11 \r
12 #include "common.h"\r
13 #include "mii.h"\r
14 \r
15 /********************************************************************/\r
16 /*\r
17  * \brief   Initialize the MII interface controller\r
18  * \param   System Clock Frequency (in MHz)\r
19  * \warning The system clock in this case is the clock that drives\r
20  *          the FEC logic.  This may be different from the speed at which \r
21  *          the CPU is operating.\r
22  * \r
23  * Initialize the MII clock (EMDC) frequency. The desired MII clock is 2.5MHz:\r
24  *\r
25  * MII Speed Setting = System_Clock / (2.5MHz * 2)\r
26  * (plus 1 to round up)\r
27  */\r
28 void\r
29 mii_init(int ch, int sys_clk_mhz)\r
30 {\r
31     ENET_MSCR/*(ch)*/ = 0\r
32 #ifdef TSIEVB/*TSI EVB requires a longer hold time than default 10 ns*/\r
33                       | ENET_MSCR_HOLDTIME(2) \r
34 #endif                      \r
35                       | ENET_MSCR_MII_SPEED((2*sys_clk_mhz/5)+1)\r
36                       ;\r
37 }\r
38 /********************************************************************/\r
39 /*!\r
40  * \brief Write a value to a PHY's MII register.\r
41  * \r
42  * \param   phy_addr    Address of the PHY\r
43  * \param   reg_addr    Address of the register in the PHY\r
44  * \param   data        Data to be written to the PHY register\r
45  * \return  0 if write is successful; 1 if write times out\r
46  *\r
47  * mii_write() polls for the FEC's MII interrupt event (which should\r
48  * be masked from the interrupt handler) and clears it. If after a\r
49  * suitable amount of time the event isn't triggered, a non-zero value \r
50  * is returned.\r
51  */\r
52 int \r
53 mii_write(int ch, int phy_addr, int reg_addr, int data)\r
54 {\r
55         int timeout;\r
56 \r
57         /* Clear the MII interrupt bit */\r
58         ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;\r
59 \r
60         /* Initiatate the MII Management write */\r
61         ENET_MMFR/*(ch)*/ = 0\r
62                 | ENET_MMFR_ST(0x01)\r
63                 | ENET_MMFR_OP(0x01)\r
64                 | ENET_MMFR_PA(phy_addr)\r
65                 | ENET_MMFR_RA(reg_addr)\r
66                 | ENET_MMFR_TA(0x02)\r
67                 | ENET_MMFR_DATA(data);\r
68 \r
69         /* Poll for the MII interrupt (interrupt should be masked) */\r
70         for (timeout = 0; timeout < MII_TIMEOUT; timeout++)\r
71         {\r
72                 if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)\r
73                         break;\r
74         }\r
75 \r
76         if(timeout == MII_TIMEOUT) \r
77                 return 1;\r
78 \r
79         /* Clear the MII interrupt bit */\r
80         ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;\r
81 \r
82         return 0;\r
83 }\r
84 /********************************************************************/\r
85 /*!\r
86  * \brief   Read a value from a PHY's MII register.\r
87  * \param   phy_addr    Address of the PHY\r
88  * \param   reg_addr    Address of the register in the PHY\r
89  * \param   data        Pointer to location were read data will be stored\r
90  * \return  0 if write is successful; 1 if write times out\r
91  *\r
92  * mii_read() polls for the FEC's MII interrupt event (which should\r
93  * be masked from the interrupt handler) and clears it. If after a\r
94  * suitable amount of time the event isn't triggered, a non-zero value \r
95  * is returned.\r
96  */\r
97 int \r
98 mii_read(int ch, int phy_addr, int reg_addr, int *data)\r
99 {\r
100         int timeout;\r
101 \r
102         /* Clear the MII interrupt bit */\r
103         ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;\r
104 \r
105         /* Initiatate the MII Management read */\r
106         ENET_MMFR/*(ch)*/ = 0\r
107                 | ENET_MMFR_ST(0x01)\r
108                 | ENET_MMFR_OP(0x2)\r
109                 | ENET_MMFR_PA(phy_addr)\r
110                 | ENET_MMFR_RA(reg_addr)\r
111                 | ENET_MMFR_TA(0x02);\r
112 \r
113         /* Poll for the MII interrupt (interrupt should be masked) */\r
114         for (timeout = 0; timeout < MII_TIMEOUT; timeout++)\r
115         {\r
116                 if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)\r
117                         break;\r
118         }\r
119     \r
120         if(timeout == MII_TIMEOUT) \r
121                 return 1;\r
122 \r
123         /* Clear the MII interrupt bit */\r
124         ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;\r
125 \r
126         *data = ENET_MMFR/*(ch)*/ & 0x0000FFFF;\r
127 \r
128         return 0;\r
129 }\r
130 /********************************************************************/\r