dp83tc811_driver.c
Go to the documentation of this file.
1 /**
2  * @file dp83tc811_driver.c
3  * @brief DP83TC811 Ethernet PHY transceiver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
37 #include "debug.h"
38 
39 
40 /**
41  * @brief DP83TC811 Ethernet PHY driver
42  **/
43 
45 {
51  NULL,
52  NULL
53 };
54 
55 
56 /**
57  * @brief DP83TC811 PHY transceiver initialization
58  * @param[in] interface Underlying network interface
59  * @return Error code
60  **/
61 
63 {
64  //Debug message
65  TRACE_INFO("Initializing DP83TC811...\r\n");
66 
67  //Undefined PHY address?
68  if(interface->phyAddr >= 32)
69  {
70  //Use the default address
71  interface->phyAddr = DP83TC811_PHY_ADDR;
72  }
73 
74  //Initialize external interrupt line driver
75  if(interface->extIntDriver != NULL)
76  {
77  interface->extIntDriver->init();
78  }
79 
80  //Reset PHY transceiver
82 
83  //Wait for the reset to complete
85  {
86  }
87 
88  //Dump PHY registers for debugging purpose
89  dp83tc811DumpPhyReg(interface);
90 
91  //Force the TCP/IP stack to poll the link state at startup
92  interface->phyEvent = TRUE;
93  //Notify the TCP/IP stack of the event
95 
96  //Successful initialization
97  return NO_ERROR;
98 }
99 
100 
101 /**
102  * @brief DP83TC811 timer handler
103  * @param[in] interface Underlying network interface
104  **/
105 
106 void dp83tc811Tick(NetInterface *interface)
107 {
108  uint16_t value;
109  bool_t linkState;
110 
111  //No external interrupt line driver?
112  if(interface->extIntDriver == NULL)
113  {
114  //Read status register
116  //Retrieve current link state
117  linkState = (value & DP83TC811_BMSR_LINK_STATUS) ? TRUE : FALSE;
118 
119  //Link up event?
120  if(linkState && !interface->linkState)
121  {
122  //Set event flag
123  interface->phyEvent = TRUE;
124  //Notify the TCP/IP stack of the event
126  }
127  //Link down event?
128  else if(!linkState && interface->linkState)
129  {
130  //Set event flag
131  interface->phyEvent = TRUE;
132  //Notify the TCP/IP stack of the event
134  }
135  }
136 }
137 
138 
139 /**
140  * @brief Enable interrupts
141  * @param[in] interface Underlying network interface
142  **/
143 
145 {
146  //Enable PHY transceiver interrupts
147  if(interface->extIntDriver != NULL)
148  {
149  interface->extIntDriver->enableIrq();
150  }
151 }
152 
153 
154 /**
155  * @brief Disable interrupts
156  * @param[in] interface Underlying network interface
157  **/
158 
160 {
161  //Disable PHY transceiver interrupts
162  if(interface->extIntDriver != NULL)
163  {
164  interface->extIntDriver->disableIrq();
165  }
166 }
167 
168 
169 /**
170  * @brief DP83TC811 event handler
171  * @param[in] interface Underlying network interface
172  **/
173 
175 {
176  uint16_t value;
177 
178  //Read status register
180 
181  //Link is up?
183  {
184  //Adjust MAC configuration parameters for proper operation
185  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
186  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
187  interface->nicDriver->updateMacConfig(interface);
188 
189  //Update link state
190  interface->linkState = TRUE;
191  }
192  else
193  {
194  //Update link state
195  interface->linkState = FALSE;
196  }
197 
198  //Process link state change event
199  nicNotifyLinkChange(interface);
200 }
201 
202 
203 /**
204  * @brief Write PHY register
205  * @param[in] interface Underlying network interface
206  * @param[in] address PHY register address
207  * @param[in] data Register value
208  **/
209 
210 void dp83tc811WritePhyReg(NetInterface *interface, uint8_t address,
211  uint16_t data)
212 {
213  //Write the specified PHY register
214  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE,
215  interface->phyAddr, address, data);
216 }
217 
218 
219 /**
220  * @brief Read PHY register
221  * @param[in] interface Underlying network interface
222  * @param[in] address PHY register address
223  * @return Register value
224  **/
225 
226 uint16_t dp83tc811ReadPhyReg(NetInterface *interface, uint8_t address)
227 {
228  //Read the specified PHY register
229  return interface->nicDriver->readPhyReg(SMI_OPCODE_READ,
230  interface->phyAddr, address);
231 }
232 
233 
234 /**
235  * @brief Dump PHY registers for debugging purpose
236  * @param[in] interface Underlying network interface
237  **/
238 
240 {
241  uint8_t i;
242 
243  //Loop through PHY registers
244  for(i = 0; i < 32; i++)
245  {
246  //Display current PHY register
247  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
248  dp83tc811ReadPhyReg(interface, i));
249  }
250 
251  //Terminate with a line feed
252  TRACE_DEBUG("\r\n");
253 }
254 
255 
256 /**
257  * @brief Write MMD extended register
258  * @param[in] interface Underlying network interface
259  * @param[in] address PHY register address
260  * @param[in] data Register value
261  **/
262 
263 void dp83tc811WriteMmdReg(NetInterface *interface, uint16_t address,
264  uint16_t data)
265 {
266  //Write the value 0x001F to register REGCR
269 
270  //Write the desired register address to register ADDAR
272 
273  //Write the value 0x401F to register REGCR
276 
277  //Write the content of the desired extended register set to register ADDAR
279 }
280 
281 
282 /**
283  * @brief Read MMD extended register
284  * @param[in] interface Underlying network interface
285  * @param[in] address PHY register address
286  * @return Register value
287  **/
288 
289 uint16_t dp83tc811ReadMmdReg(NetInterface *interface, uint16_t address)
290 {
291  //Write the value 0x001F to register REGCR
294 
295  //Write the desired register address to register ADDAR
297 
298  //Write the value 0x401F to register REGCR
301 
302  //Read the content of the desired extended register set in register ADDAR
303  return dp83tc811ReadPhyReg(interface, DP83TC811_ADDAR);
304 }
305 
306 
307 /**
308  * @brief Write MMD1 extended register
309  * @param[in] interface Underlying network interface
310  * @param[in] address PHY register address
311  * @param[in] data Register value
312  **/
313 
314 void dp83tc811WriteMmd1Reg(NetInterface *interface, uint16_t address,
315  uint16_t data)
316 {
317  //Write the value 0x0001 to register REGCR
320 
321  //Write the desired register address to register ADDAR
323 
324  //Write the value 0x4001 to register REGCR
327 
328  //Write the content of the desired extended register set to register ADDAR
330 }
331 
332 
333 /**
334  * @brief Read MMD1 extended register
335  * @param[in] interface Underlying network interface
336  * @param[in] address PHY register address
337  * @return Register value
338  **/
339 
340 uint16_t dp83tc811ReadMmd1Reg(NetInterface *interface, uint16_t address)
341 {
342  //Write the value 0x0001 to register REGCR
345 
346  //Write the desired register address to register ADDAR
348 
349  //Write the value 0x4001 to register REGCR
352 
353  //Read the content of the desired extended register set in register ADDAR
354  return dp83tc811ReadPhyReg(interface, DP83TC811_ADDAR);
355 }
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:525
int bool_t
Definition: compiler_port.h:49
#define DP83TC811_BMCR
#define TRUE
Definition: os_port.h:50
PHY driver.
Definition: nic.h:214
uint16_t dp83tc811ReadMmdReg(NetInterface *interface, uint16_t address)
Read MMD extended register.
#define DP83TC811_REGCR
void dp83tc811Tick(NetInterface *interface)
DP83TC811 timer handler.
void dp83tc811EventHandler(NetInterface *interface)
DP83TC811 event handler.
#define SMI_OPCODE_WRITE
Definition: nic.h:62
void dp83tc811DisableIrq(NetInterface *interface)
Disable interrupts.
error_t dp83tc811Init(NetInterface *interface)
DP83TC811 PHY transceiver initialization.
#define FALSE
Definition: os_port.h:46
void dp83tc811DumpPhyReg(NetInterface *interface)
Dump PHY registers for debugging purpose.
void dp83tc811EnableIrq(NetInterface *interface)
Enable interrupts.
error_t
Error codes.
Definition: error.h:42
DP83TC811 Ethernet PHY transceiver.
#define DP83TC811_REGCR_COMMAND_DATA_NO_POST_INC
#define NetInterface
Definition: net.h:36
void dp83tc811WriteMmd1Reg(NetInterface *interface, uint16_t address, uint16_t data)
Write MMD1 extended register.
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
#define TRACE_INFO(...)
Definition: debug.h:94
#define DP83TC811_BMCR_RESET
#define DP83TC811_REGCR_DEVAD_1
#define DP83TC811_BMSR
#define TRACE_DEBUG(...)
Definition: debug.h:106
#define DP83TC811_BMSR_LINK_STATUS
#define DP83TC811_REGCR_COMMAND_ADDR
void dp83tc811WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
Write PHY register.
#define DP83TC811_REGCR_DEVAD_31
#define DP83TC811_PHY_ADDR
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void dp83tc811WriteMmdReg(NetInterface *interface, uint16_t address, uint16_t data)
Write MMD extended register.
uint8_t value[]
Definition: dtls_misc.h:150
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
#define DP83TC811_ADDAR
Success.
Definition: error.h:44
Debugging facilities.
uint16_t dp83tc811ReadMmd1Reg(NetInterface *interface, uint16_t address)
Read MMD1 extended register.
const PhyDriver dp83tc811PhyDriver
DP83TC811 Ethernet PHY driver.
uint16_t dp83tc811ReadPhyReg(NetInterface *interface, uint8_t address)
Read PHY register.