LPCOpen Platform for LPC18XX/43XX microcontrollers
18XX43XX
LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers
Main Page
Modules
Data Structures
Files
File List
Globals
software
lpc_core
lpc_board
board_common
lpc_phy_dp83848.c
Go to the documentation of this file.
1
/*
2
* @brief Mational DP83848 simple PHY driver
3
*
4
* @note
5
* Copyright(C) NXP Semiconductors, 2012
6
* All rights reserved.
7
*
8
* @par
9
* Software that is described herein is for illustrative purposes only
10
* which provides customers with programming information regarding the
11
* LPC products. This software is supplied "AS IS" without any warranties of
12
* any kind, and NXP Semiconductors and its licensor disclaim any and
13
* all warranties, express or implied, including all implied warranties of
14
* merchantability, fitness for a particular purpose and non-infringement of
15
* intellectual property rights. NXP Semiconductors assumes no responsibility
16
* or liability for the use of the software, conveys no license or rights under any
17
* patent, copyright, mask work right, or any other intellectual property rights in
18
* or to any products. NXP Semiconductors reserves the right to make changes
19
* in the software without notification. NXP Semiconductors also makes no
20
* representation or warranty that such application will be suitable for the
21
* specified use without further testing or modification.
22
*
23
* @par
24
* Permission to use, copy, modify, and distribute this software and its
25
* documentation is hereby granted, under NXP Semiconductors' and its
26
* licensor's relevant copyrights in the software, without fee, provided that it
27
* is used in conjunction with NXP Semiconductors microcontrollers. This
28
* copyright, permission, and disclaimer notice must appear in all copies of
29
* this code.
30
*/
31
32
#include "
chip.h
"
33
#include "
lpc_phy.h
"
34
43
#define DP8_BMCR_REG 0x0
44
#define DP8_BMSR_REG 0x1
45
#define DP8_ANADV_REG 0x4
46
#define DP8_ANLPA_REG 0x5
47
#define DP8_ANEEXP_REG 0x6
48
#define DP8_PHY_STAT_REG 0x10
49
#define DP8_PHY_INT_CTL_REG 0x11
50
#define DP8_PHY_RBR_REG 0x17
51
#define DP8_PHY_STS_REG 0x19
53
/* DP83848 Control register definitions */
54
#define DP8_RESET (1 << 15)
55
#define DP8_LOOPBACK (1 << 14)
56
#define DP8_SPEED_SELECT (1 << 13)
57
#define DP8_AUTONEG (1 << 12)
58
#define DP8_POWER_DOWN (1 << 11)
59
#define DP8_ISOLATE (1 << 10)
60
#define DP8_RESTART_AUTONEG (1 << 9)
61
#define DP8_DUPLEX_MODE (1 << 8)
62
#define DP8_COLLISION_TEST (1 << 7)
64
/* DP83848 Status register definitions */
65
#define DP8_100BASE_T4 (1 << 15)
66
#define DP8_100BASE_TX_FD (1 << 14)
67
#define DP8_100BASE_TX_HD (1 << 13)
68
#define DP8_10BASE_T_FD (1 << 12)
69
#define DP8_10BASE_T_HD (1 << 11)
70
#define DP8_MF_PREAMB_SUPPR (1 << 6)
71
#define DP8_AUTONEG_COMP (1 << 5)
72
#define DP8_RMT_FAULT (1 << 4)
73
#define DP8_AUTONEG_ABILITY (1 << 3)
74
#define DP8_LINK_STATUS (1 << 2)
75
#define DP8_JABBER_DETECT (1 << 1)
76
#define DP8_EXTEND_CAPAB (1 << 0)
78
/* DP83848 PHY RBR MII dode definitions */
79
#define DP8_RBR_RMII_MODE (1 << 5)
81
/* DP83848 PHY status definitions */
82
#define DP8_REMOTEFAULT (1 << 6)
83
#define DP8_FULLDUPLEX (1 << 2)
84
#define DP8_SPEED10MBPS (1 << 1)
85
#define DP8_VALID_LINK (1 << 0)
87
/* DP83848 PHY ID register definitions */
88
#define DP8_PHYID1_OUI 0x2000
89
#define DP8_PHYID2_OUI 0x5c90
91
/* DP83848 PHY update flags */
92
static
uint32_t
physts
,
olddphysts
;
93
94
/* PHY update counter for state machine */
95
static
int32_t
phyustate
;
96
97
/* Pointer to delay function used for this driver */
98
static
p_msDelay_func_t
pDelayMs
;
99
100
/* Write to the PHY. Will block for delays based on the pDelayMs function. Returns
101
true on success, or false on failure */
102
static
Status
lpc_mii_write
(uint8_t reg, uint16_t data)
103
{
104
Status
sts =
ERROR
;
105
int32_t mst = 250;
106
107
/* Write value for register */
108
Chip_ENET_StartMIIWrite
(
LPC_ETHERNET
, reg, data);
109
110
/* Wait for unbusy status */
111
while
(mst > 0) {
112
if
(
Chip_ENET_IsMIIBusy
(
LPC_ETHERNET
)) {
113
mst--;
114
pDelayMs
(1);
115
}
116
else
{
117
mst = 0;
118
sts =
SUCCESS
;
119
}
120
}
121
122
return
sts;
123
}
124
125
/* Read from the PHY. Will block for delays based on the pDelayMs function. Returns
126
true on success, or false on failure */
127
static
Status
lpc_mii_read
(uint8_t reg, uint16_t *data)
128
{
129
Status
sts =
ERROR
;
130
int32_t mst = 250;
131
132
/* Start register read */
133
Chip_ENET_StartMIIRead
(
LPC_ETHERNET
, reg);
134
135
/* Wait for unbusy status */
136
while
(mst > 0) {
137
if
(!
Chip_ENET_IsMIIBusy
(
LPC_ETHERNET
)) {
138
mst = 0;
139
*data =
Chip_ENET_ReadMIIData
(
LPC_ETHERNET
);
140
sts =
SUCCESS
;
141
}
142
else
{
143
mst--;
144
pDelayMs
(1);
145
}
146
}
147
148
return
sts;
149
}
150
151
/* Update PHY status from passed value */
152
static
void
lpc_update_phy_sts
(uint16_t linksts)
153
{
154
/* Update link active status */
155
if
(linksts &
DP8_VALID_LINK
) {
156
physts
|=
PHY_LINK_CONNECTED
;
157
}
158
else
{
159
physts
&= ~
PHY_LINK_CONNECTED
;
160
}
161
162
/* Full or half duplex */
163
if
(linksts &
DP8_FULLDUPLEX
) {
164
physts
|=
PHY_LINK_FULLDUPLX
;
165
}
166
else
{
167
physts
&= ~
PHY_LINK_FULLDUPLX
;
168
}
169
170
/* Configure 100MBit/10MBit mode. */
171
if
(linksts &
DP8_SPEED10MBPS
) {
172
physts
&= ~
PHY_LINK_SPEED100
;
173
}
174
else
{
175
physts
|=
PHY_LINK_SPEED100
;
176
}
177
178
/* If the status has changed, indicate via change flag */
179
if
((
physts
& (
PHY_LINK_SPEED100
|
PHY_LINK_FULLDUPLX
|
PHY_LINK_CONNECTED
)) !=
180
(
olddphysts
& (
PHY_LINK_SPEED100
|
PHY_LINK_FULLDUPLX
|
PHY_LINK_CONNECTED
))) {
181
olddphysts
=
physts
;
182
physts
|=
PHY_LINK_CHANGED
;
183
}
184
}
185
186
/* Initialize the DP83848 PHY */
187
uint32_t
lpc_phy_init
(
bool
rmii,
p_msDelay_func_t
pDelayMsFunc)
188
{
189
uint16_t tmp;
190
int32_t i;
191
192
pDelayMs
= pDelayMsFunc;
193
194
/* Initial states for PHY status and state machine */
195
olddphysts
=
physts
=
phyustate
= 0;
196
197
/* Only first read and write are checked for failure */
198
/* Put the DP83848C in reset mode and wait for completion */
199
if
(
lpc_mii_write
(
DP8_BMCR_REG
,
DP8_RESET
) !=
SUCCESS
) {
200
return
ERROR
;
201
}
202
i = 400;
203
while
(i > 0) {
204
pDelayMs
(1);
205
if
(
lpc_mii_read
(
DP8_BMCR_REG
, &tmp) !=
SUCCESS
) {
206
return
ERROR
;
207
}
208
209
if
(!(tmp & (
DP8_RESET
|
DP8_POWER_DOWN
))) {
210
i = -1;
211
}
212
else
{
213
i--;
214
}
215
}
216
/* Timeout? */
217
if
(i == 0) {
218
return
ERROR
;
219
}
220
221
#if 0
222
/* Setup link based on configuration options */
223
#if PHY_USE_AUTONEG == 1
224
tmp =
DP8_AUTONEG
;
225
#else
226
tmp = 0;
227
#endif
228
#if PHY_USE_100MBS == 1
229
tmp |=
DP8_SPEED_SELECT
;
230
#endif
231
#if PHY_USE_FULL_DUPLEX == 1
232
tmp |=
DP8_DUPLEX_MODE
;
233
#endif
234
235
#else
236
tmp =
DP8_AUTONEG
;
237
#endif
238
239
lpc_mii_write
(
DP8_BMCR_REG
, tmp);
240
241
/* Enable RMII mode for PHY */
242
if
(rmii) {
243
lpc_mii_write
(
DP8_PHY_RBR_REG
,
DP8_RBR_RMII_MODE
);
244
}
245
246
/* The link is not set active at this point, but will be detected
247
later */
248
249
return
SUCCESS
;
250
}
251
252
/* Phy status update state machine */
253
uint32_t
lpcPHYStsPoll
(
void
)
254
{
255
switch
(
phyustate
) {
256
default
:
257
case
0:
258
/* Read BMSR to clear faults */
259
Chip_ENET_StartMIIRead
(
LPC_ETHERNET
,
DP8_PHY_STAT_REG
);
260
physts
&= ~
PHY_LINK_CHANGED
;
261
physts
=
physts
|
PHY_LINK_BUSY
;
262
phyustate
= 1;
263
break
;
264
265
case
1:
266
/* Wait for read status state */
267
if
(!
Chip_ENET_IsMIIBusy
(
LPC_ETHERNET
)) {
268
/* Update PHY status */
269
physts
&= ~
PHY_LINK_BUSY
;
270
lpc_update_phy_sts
(
Chip_ENET_ReadMIIData
(
LPC_ETHERNET
));
271
phyustate
= 0;
272
}
273
break
;
274
}
275
276
return
physts
;
277
}
278
Generated on Fri Feb 20 2015 21:29:41 for LPCOpen Platform for LPC18XX/43XX microcontrollers by
1.8.3.1