source: UsbWattMeter/trunk/lwip-1.4.1/ports/grsakura/ether_phy.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 10.4 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 * Copyright (C) 2014 Cores Co., Ltd. Japan
7 *
8 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
9 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
10 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
11 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
12 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
13 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
14 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
15 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
16ƒƒ“ƒgi—˜—p
17 * ŽÒƒ}ƒjƒ…
18ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
19 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
20 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
21 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
22 * ‚ƁD
23 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
24ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
25ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
26 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
27 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
28 * •ñ‚·‚邱‚ƁD
29 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
30 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
31 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
32 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
33 * –Ɛӂ·‚邱‚ƁD
34 *
35 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
36 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
37 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
38 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
39 * ‚̐ӔC‚𕉂í‚È‚¢D
40 *
41 * @(#) $Id: ether_phy.c 164 2016-03-07 11:33:50Z coas-nagasima $
42 */
43
44#include "ether_phy.h"
45#include <kernel.h>
46#include <sil.h>
47
48#define PHY_CONTROL_REGISTER 0x00
49
50#define PHY_CONTROL_RESET 0x8000
51#define PHY_CONTROL_LOOPBACK 0x4000
52#define PHY_CONTROL_SPEED_SELECT 0x2000
53#define PHY_CONTROL_A_N_ENABLE 0x1000
54#define PHY_CONTROL_POWER_DOWN 0x0800
55#define PHY_CONTROL_ISOLATE 0x0400
56#define PHY_CONTROL_RESTART_A_N 0x0200
57#define PHY_CONTROL_DUPLEX_MODE 0x0100
58#define PHY_CONTROL_COLLISION_TEST 0x0080
59
60#define PHY_STATUS_REGISTER 0x01
61
62#define PHY_STATUS_100BASE_T4 0x8000
63#define PHY_STATUS_100BASE_TX_FULL_DUPLEX 0x4000
64#define PHY_STATUS_100BASE_TX_HALF_DUPLEX 0x2000
65#define PHY_STATUS_10BASE_T_FULL_DUPLEX 0x1000
66#define PHY_STATUS_10BASE_T_HALF_DUPLEX 0x0800
67#define PHY_STATUS_A_N_COMPLETE 0x0020
68#define PHY_STATUS_REMOTE_FAULT 0x0010
69#define PHY_STATUS_A_N_ABILITY 0x0008
70#define PHY_STATUS_LINK_STATUS 0x0004
71#define PHY_STATUS_JABBER_DETECT 0x0002
72#define PHY_STATUS_EXTENDED_CAPABILITY 0x0001
73
74#define PHY_AN_ADVERTISEMENT_REGISTER 0x04
75
76#define PHY_AN_AD_100BASE_T4 0x0200
77#define PHY_AN_AD_100BASE_TX_FULL_DUPLEX 0x0100
78#define PHY_AN_AD_100BASE_TX_HALF_DUPLEX 0x0080
79#define PHY_AN_AD_10BASE_T_FULL_DUPLEX 0x0040
80#define PHY_AN_AD_10BASE_T_HALF_DUPLEX 0x0020
81#define PHY_AN_AD_SELECTOR_FIELD 0x0001
82
83#define PHY_AN_STATUS_REGISTER 0x05
84
85#define PHY_AN_STATUS_100BASE_T4 0x0200
86#define PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX 0x0100
87#define PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX 0x0080
88#define PHY_AN_STATUS_10BASE_T_FULL_DUPLEX 0x0040
89#define PHY_AN_STATUS_10BASE_T_HALF_DUPLEX 0x0020
90
91static void phy_write_bit(bool_t bit);
92static void phy_release_bus();
93static bool_t phy_read_bit();
94static void phy_single_rel_bus();
95
96PHY_STATE_T phy_reset(PHY_STATE_T state, uint8_t phy_addr)
97{
98 switch(state){
99 case PHY_STATE_UNINIT:
100 /* PHY‚̃ŠƒZƒbƒg */
101 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_RESET);
102
103 /* 500ms‘Ò‚Â */
104 /* tslp_tsk(500); •s—vH */
105 /* continue; */
106 case PHY_STATE_RESETING:
107 /* ƒŠƒZƒbƒgŠ®—¹‚ÌŠm”F */
108 if((phy_read_reg(phy_addr, PHY_CONTROL_REGISTER) & PHY_CONTROL_RESET) != 0)
109 return PHY_STATE_RESETING;
110
111 return PHY_STATE_RESET;
112 default:
113 return state;
114 }
115}
116
117PHY_STATE_T phy_initialize(PHY_STATE_T state, uint8_t phy_addr, PHY_MODE_T *mode)
118{
119#ifndef __RX
120 static int reset = 0;
121#endif
122 uint16_t status;
123 *mode = (PHY_MODE_T)0;
124
125 switch(state){
126 case PHY_STATE_RESET:
127#ifndef __RX
128 reset++;
129 if(reset < 2){
130#endif
131 /* ƒŠƒ“ƒNŠ®—¹‚ÌŠm”F */
132 if(!phy_is_link(phy_addr))
133 return PHY_STATE_RESET;
134#ifndef __RX
135 }
136 reset = 0;
137#endif
138 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“‚Ì‚¨’m‚点‚ð—LŒø‚ɐݒè */
139 phy_write_reg(phy_addr, PHY_AN_ADVERTISEMENT_REGISTER,
140 PHY_AN_AD_100BASE_T4 | PHY_AN_AD_100BASE_TX_FULL_DUPLEX | PHY_AN_AD_100BASE_TX_HALF_DUPLEX
141 | PHY_AN_AD_10BASE_T_FULL_DUPLEX | PHY_AN_AD_10BASE_T_HALF_DUPLEX | PHY_AN_AD_SELECTOR_FIELD);
142
143 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“‚ð—LŒø‚ɐݒè */
144 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_SPEED_SELECT | PHY_CONTROL_A_N_ENABLE);
145
146 /* continue; */
147 case PHY_STATE_LINKED:
148#ifndef __RX
149 reset++;
150 if(reset < 2){
151#endif
152 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“Š®—¹‚ÌŠm”F */
153 if((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_A_N_COMPLETE) == 0)
154 return PHY_STATE_LINKED;
155#ifndef __RX
156 }
157#endif
158 status = phy_read_reg(phy_addr, PHY_AN_STATUS_REGISTER);
159
160 if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_10BASE_T_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX)) != 0)
161 *mode = (PHY_MODE_T)(((int)*mode) | 0x01);
162
163 if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX)) != 0)
164 *mode = (PHY_MODE_T)(((int)*mode) | 0x02);
165
166 return PHY_STATE_NEGOTIATED;
167 }
168
169 return state;
170}
171
172bool_t phy_is_link(uint8_t phy_addr)
173{
174#ifdef __RX
175 /* ƒŠƒ“ƒN‚ÌŠm”F */
176 return (phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_LINK_STATUS) != 0;
177#else
178 return true;
179#endif
180}
181
182uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
183{
184 uint16_t result = 0, bit;
185 int i;
186
187 /* PRE F32ŒÂ‚̘A‘±‚µ‚½1b */
188 for (i = 0; i < 32; i++)
189 phy_write_bit(true);
190
191 /* ST FƒtƒŒ[ƒ€‚̐擪‚ðŽ¦‚·01b‚̃‰ƒCƒg */
192 phy_write_bit(false);
193 phy_write_bit(true);
194
195 /* OP FƒAƒNƒZƒXŽí•Ê‚ðŽ¦‚·ƒR[ƒh‚̃‰ƒCƒg */
196 phy_write_bit(true);
197 phy_write_bit(false);
198
199 /* PHYAD FPHY-LSI‚̃AƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB ‚©‚珇ŽŸƒ‰ƒCƒgjB */
200 phy_write_bit((phy_addr & 0x10) != 0);
201 phy_write_bit((phy_addr & 0x08) != 0);
202 phy_write_bit((phy_addr & 0x04) != 0);
203 phy_write_bit((phy_addr & 0x02) != 0);
204 phy_write_bit((phy_addr & 0x01) != 0);
205
206 /* REGAD FƒŒƒWƒXƒ^ƒAƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB‚©‚珇ŽŸƒ‰ƒCƒgjB */
207 phy_write_bit((reg_addr & 0x10) != 0);
208 phy_write_bit((reg_addr & 0x08) != 0);
209 phy_write_bit((reg_addr & 0x04) != 0);
210 phy_write_bit((reg_addr & 0x02) != 0);
211 phy_write_bit((reg_addr & 0x01) != 0);
212
213 /* TA FMII/RMIIƒCƒ“ƒ^ƒtƒF[ƒXã‚Ńf[ƒ^‚Ì‘—MŒ³‚ðØ‚è‘Ö‚¦‚鎞ŠÔ */
214 /* uƒoƒX‰ð•úviZ0‚Æ•\‹Lj‚ðs‚¤ */
215 phy_release_bus();
216
217 /* DATA F16ƒrƒbƒg‚̃f[ƒ^BMSB‚©‚珇ŽŸƒŠ[ƒh */
218 for (bit = 0x8000; bit != 0; bit >>= 1) {
219 if(phy_read_bit())
220 result |= bit;
221 }
222
223 /* IDLE FŽŸ‚ÌMIIŠÇ—ƒtƒH[ƒ}ƒbƒg“ü—Í‚Ü‚Å‚Ì‘Ò‹@ŽžŠÔ */
224 /* ‚·‚Å‚ÉTAŽž‚ɃoƒX‰ð•úÏ‚Ý‚Å‚ ‚萧Œä•s—v */
225 phy_release_bus();
226
227 return result;
228}
229
230void phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_data)
231{
232 int i;
233 uint16_t bit;
234
235 /* PRE F32ŒÂ‚̘A‘±‚µ‚½1b */
236 for (i = 0; i < 32; i++)
237 phy_write_bit(true);
238
239 /* ST FƒtƒŒ[ƒ€‚̐擪‚ðŽ¦‚·01b‚̃‰ƒCƒg */
240 phy_write_bit(false);
241 phy_write_bit(true);
242
243 /* OP FƒAƒNƒZƒXŽí•Ê‚ðŽ¦‚·ƒR[ƒh‚̃‰ƒCƒg */
244 phy_write_bit(false);
245 phy_write_bit(true);
246
247 /* PHYAD FPHY-LSI‚̃AƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB ‚©‚珇ŽŸƒ‰ƒCƒgjB */
248 phy_write_bit((phy_addr & 0x10) != 0);
249 phy_write_bit((phy_addr & 0x08) != 0);
250 phy_write_bit((phy_addr & 0x04) != 0);
251 phy_write_bit((phy_addr & 0x02) != 0);
252 phy_write_bit((phy_addr & 0x01) != 0);
253
254 /* REGAD FƒŒƒWƒXƒ^ƒAƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB‚©‚珇ŽŸƒ‰ƒCƒgjB */
255 phy_write_bit((reg_addr & 0x10) != 0);
256 phy_write_bit((reg_addr & 0x08) != 0);
257 phy_write_bit((reg_addr & 0x04) != 0);
258 phy_write_bit((reg_addr & 0x02) != 0);
259 phy_write_bit((reg_addr & 0x01) != 0);
260
261 /* TA FMII/RMIIƒCƒ“ƒ^ƒtƒF[ƒXã‚Ńf[ƒ^‚Ì‘—MŒ³‚ðØ‚è‘Ö‚¦‚鎞ŠÔ */
262 /* 10b‚ðƒ‰ƒCƒg */
263 phy_write_bit(true);
264 phy_write_bit(false);
265
266 /* DATA F16ƒrƒbƒg‚̃f[ƒ^BMSB‚©‚珇ŽŸƒ‰ƒCƒg */
267 for (bit = 0x8000; bit != 0; bit >>= 1) {
268 phy_write_bit((reg_data & bit) != 0);
269 }
270
271 /* IDLE FŽŸ‚ÌMIIŠÇ—ƒtƒH[ƒ}ƒbƒg“ü—Í‚Ü‚Å‚Ì‘Ò‹@ŽžŠÔ */
272 /* u’P“ƃoƒX‰ð•úviX‚Æ•\‹Lj‚ðs‚¤ */
273 phy_single_rel_bus();
274}
275
276#define ETHERC_PIR_WAIT 4
277
278/*
279 * 1 ƒrƒbƒgƒf[ƒ^‚̃‰ƒCƒg
280 */
281static void phy_write_bit(bool_t bit)
282{
283 int i;
284 uint32_t data = bit ? ETHERC_PIR_MDO : 0;
285
286 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
287 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
288
289 for(i = ETHERC_PIR_WAIT; i > 0; i--);
290
291 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
292 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | ETHERC_PIR_MDC);
293
294 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
295
296 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
297 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
298
299 for(i = ETHERC_PIR_WAIT; i > 0; i--);
300}
301
302/*
303 * ƒoƒX‰ð•ú
304 */
305static void phy_release_bus()
306{
307 int i;
308
309 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
310 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
311
312 for(i = ETHERC_PIR_WAIT; i > 0; i--);
313
314 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
315 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
316
317 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
318
319 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
320 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
321
322 for(i = ETHERC_PIR_WAIT; i > 0; i--);
323}
324
325/*
326 * 1 ƒrƒbƒgƒf[ƒ^‚̃Š[ƒh
327 */
328static bool_t phy_read_bit()
329{
330 bool_t bit;
331 int i;
332
333 for(i = ETHERC_PIR_WAIT; i > 0; i--);
334
335 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
336 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
337
338 for(i = ETHERC_PIR_WAIT; i > 0; i--);
339
340 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
341 bit = (sil_rew_mem(ETHERC_PIR) & ETHERC_PIR_MDI) != 0;
342
343 for(i = ETHERC_PIR_WAIT; i > 0; i--);
344
345 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
346 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
347
348 for(i = ETHERC_PIR_WAIT; i > 0; i--);
349
350 return bit;
351}
352
353/*
354 * ’P“ƃoƒX‰ð•ú
355 */
356static void phy_single_rel_bus()
357{
358 int i;
359
360 for(i = ETHERC_PIR_WAIT; i > 0; i--);
361
362 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
363 sil_wrw_mem(ETHERC_PIR, ETHERC_PIR_MMD | ETHERC_PIR_MDC);
364
365 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
366
367 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
368 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
369
370 for(i = ETHERC_PIR_WAIT; i > 0; i--);
371}
Note: See TracBrowser for help on using the repository browser.