upd60611_driver.c
Go to the documentation of this file.
1 /**
2  * @file upd60611_driver.c
3  * @brief uPD60611 Ethernet PHY transceiver
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
35 #include "debug.h"
36 
37 
38 /**
39  * @brief uPD60611 Ethernet PHY driver
40  **/
41 
43 {
49 };
50 
51 
52 /**
53  * @brief uPD60611 PHY transceiver initialization
54  * @param[in] interface Underlying network interface
55  * @return Error code
56  **/
57 
59 {
60  //Debug message
61  TRACE_INFO("Initializing uPD60611...\r\n");
62 
63  //Reset PHY transceiver
65  //Wait for the reset to complete
67 
68  //Dump PHY registers for debugging purpose
69  upd60611DumpPhyReg(interface);
70 
71  //Force the TCP/IP stack to poll the link state at startup
72  interface->phyEvent = TRUE;
73  //Notify the TCP/IP stack of the event
75 
76  //Successful initialization
77  return NO_ERROR;
78 }
79 
80 
81 /**
82  * @brief uPD60611 timer handler
83  * @param[in] interface Underlying network interface
84  **/
85 
86 void upd60611Tick(NetInterface *interface)
87 {
88  uint16_t value;
89  bool_t linkState;
90 
91  //Read basic status register
93  //Retrieve current link state
94  linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE;
95 
96  //Link up event?
97  if(linkState && !interface->linkState)
98  {
99  //Set event flag
100  interface->phyEvent = TRUE;
101  //Notify the TCP/IP stack of the event
103  }
104  //Link down event?
105  else if(!linkState && interface->linkState)
106  {
107  //Set event flag
108  interface->phyEvent = TRUE;
109  //Notify the TCP/IP stack of the event
111  }
112 }
113 
114 
115 /**
116  * @brief Enable interrupts
117  * @param[in] interface Underlying network interface
118  **/
119 
121 {
122 }
123 
124 
125 /**
126  * @brief Disable interrupts
127  * @param[in] interface Underlying network interface
128  **/
129 
131 {
132 }
133 
134 
135 /**
136  * @brief uPD60611 event handler
137  * @param[in] interface Underlying network interface
138  **/
139 
141 {
142  uint16_t value;
143  bool_t linkState;
144 
145  //Any link failure condition is latched in the BMSR register... Reading
146  //the register twice will always return the actual link status
149 
150  //Retrieve current link state
151  linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE;
152 
153  //Link is up?
154  if(linkState && !interface->linkState)
155  {
156  //Read PHY special control/status register
158 
159  //Check current operation mode
160  switch(value & PSCSR_HCDSPEED_MASK)
161  {
162  //10BASE-T
163  case PSCSR_HCDSPEED_10BT:
164  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
165  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
166  break;
167  //10BASE-T full-duplex
169  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
170  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
171  break;
172  //100BASE-TX
174  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
175  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
176  break;
177  //100BASE-TX full-duplex
179  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
180  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
181  break;
182  //Unknown operation mode
183  default:
184  //Debug message
185  TRACE_WARNING("Invalid Duplex mode\r\n");
186  break;
187  }
188 
189  //Update link state
190  interface->linkState = TRUE;
191 
192  //Adjust MAC configuration parameters for proper operation
193  interface->nicDriver->updateMacConfig(interface);
194 
195  //Process link state change event
196  nicNotifyLinkChange(interface);
197  }
198  //Link is down?
199  else if(!linkState && interface->linkState)
200  {
201  //Update link state
202  interface->linkState = FALSE;
203 
204  //Process link state change event
205  nicNotifyLinkChange(interface);
206  }
207 }
208 
209 
210 /**
211  * @brief Write PHY register
212  * @param[in] interface Underlying network interface
213  * @param[in] address PHY register address
214  * @param[in] data Register value
215  **/
216 
217 void upd60611WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
218 {
219  uint8_t phyAddr;
220 
221  //Get the address of the PHY transceiver
222  if(interface->phyAddr < 32)
223  phyAddr = interface->phyAddr;
224  else
225  phyAddr = UPD60611_PHY_ADDR;
226 
227  //Write the specified PHY register
228  interface->nicDriver->writePhyReg(phyAddr, address, data);
229 }
230 
231 
232 /**
233  * @brief Read PHY register
234  * @param[in] interface Underlying network interface
235  * @param[in] address PHY register address
236  * @return Register value
237  **/
238 
239 uint16_t upd60611ReadPhyReg(NetInterface *interface, uint8_t address)
240 {
241  uint8_t phyAddr;
242 
243  //Get the address of the PHY transceiver
244  if(interface->phyAddr < 32)
245  phyAddr = interface->phyAddr;
246  else
247  phyAddr = UPD60611_PHY_ADDR;
248 
249  //Read the specified PHY register
250  return interface->nicDriver->readPhyReg(phyAddr, address);
251 }
252 
253 
254 /**
255  * @brief Dump PHY registers for debugging purpose
256  * @param[in] interface Underlying network interface
257  **/
258 
260 {
261  uint8_t i;
262 
263  //Loop through PHY registers
264  for(i = 0; i < 32; i++)
265  {
266  //Display current PHY register
267  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, upd60611ReadPhyReg(interface, i));
268  }
269 
270  //Terminate with a line feed
271  TRACE_DEBUG("\r\n");
272 }
#define UPD60611_PHY_REG_BMCR
void nicNotifyLinkChange(NetInterface *interface)
Process link state change event.
Definition: nic.c:298
uPD60611 Ethernet PHY transceiver
TCP/IP stack core.
Debugging facilities.
void upd60611EventHandler(NetInterface *interface)
uPD60611 event handler
#define BMSR_LINK_STATUS
Definition: ar8031_driver.h:95
#define PSCSR_HCDSPEED_100BTX
#define TRUE
Definition: os_port.h:48
void upd60611EnableIrq(NetInterface *interface)
Enable interrupts.
PHY driver.
Definition: nic.h:196
#define UPD60611_PHY_ADDR
#define BMCR_RESET
Definition: ar8031_driver.h:71
#define PSCSR_HCDSPEED_MASK
const PhyDriver upd60611PhyDriver
uPD60611 Ethernet PHY driver
#define TRACE_INFO(...)
Definition: debug.h:86
Success.
Definition: error.h:42
Ipv6Addr address
OsEvent netEvent
Definition: net.c:72
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
#define TRACE_WARNING(...)
Definition: debug.h:78
void upd60611DisableIrq(NetInterface *interface)
Disable interrupts.
uint8_t data[]
Definition: dtls_misc.h:167
error_t upd60611Init(NetInterface *interface)
uPD60611 PHY transceiver initialization
#define NetInterface
Definition: net.h:34
void upd60611Tick(NetInterface *interface)
uPD60611 timer handler
uint8_t value[]
Definition: dtls_misc.h:141
#define PSCSR_HCDSPEED_10BT
#define UPD60611_PHY_REG_PSCSR
#define UPD60611_PHY_REG_BMSR
uint16_t upd60611ReadPhyReg(NetInterface *interface, uint8_t address)
Read PHY register.
#define PSCSR_HCDSPEED_10BT_FD
#define PSCSR_HCDSPEED_100BTX_FD
void upd60611DumpPhyReg(NetInterface *interface)
Dump PHY registers for debugging purpose.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
void upd60611WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
Write PHY register.
#define TRACE_DEBUG(...)
Definition: debug.h:98