source: rubycfg_asp/trunk/asp_dcre/tinet/netdev/if_rx62n/ether_phy.c@ 313

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

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.2 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 * 上記著作権者
9は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11 * 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20 * 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22 * の無保証規定を掲載すること.
23 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24 * 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26 * と.
27 * (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
31 * (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34 * 報告すること.
35 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36 * 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40 * 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42 * å…
43è²¬ã™ã‚‹ã“と.
44 *
45 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50 * の責任を負わない.
51 *
52 * @(#) $Id: ether_phy.c 313 2017-07-23 04:50:32Z coas-nagasima $
53 */
54
55#include "ether_phy.h"
56#include <kernel.h>
57#include <tinet_config.h>
58#include <sil.h>
59
60#define PHY_CONTROL_REGISTER 0x00
61
62#define PHY_CONTROL_RESET 0x8000
63#define PHY_CONTROL_LOOPBACK 0x4000
64#define PHY_CONTROL_SPEED_SELECT 0x2000
65#define PHY_CONTROL_A_N_ENABLE 0x1000
66#define PHY_CONTROL_POWER_DOWN 0x0800
67#define PHY_CONTROL_ISOLATE 0x0400
68#define PHY_CONTROL_RESTART_A_N 0x0200
69#define PHY_CONTROL_DUPLEX_MODE 0x0100
70#define PHY_CONTROL_COLLISION_TEST 0x0080
71
72#define PHY_STATUS_REGISTER 0x01
73
74#define PHY_STATUS_100BASE_T4 0x8000
75#define PHY_STATUS_100BASE_TX_FULL_DUPLEX 0x4000
76#define PHY_STATUS_100BASE_TX_HALF_DUPLEX 0x2000
77#define PHY_STATUS_10BASE_T_FULL_DUPLEX 0x1000
78#define PHY_STATUS_10BASE_T_HALF_DUPLEX 0x0800
79#define PHY_STATUS_A_N_COMPLETE 0x0020
80#define PHY_STATUS_REMOTE_FAULT 0x0010
81#define PHY_STATUS_A_N_ABILITY 0x0008
82#define PHY_STATUS_LINK_STATUS 0x0004
83#define PHY_STATUS_JABBER_DETECT 0x0002
84#define PHY_STATUS_EXTENDED_CAPABILITY 0x0001
85
86#define PHY_AN_ADVERTISEMENT_REGISTER 0x04
87
88#define PHY_AN_AD_100BASE_T4 0x0200
89#define PHY_AN_AD_100BASE_TX_FULL_DUPLEX 0x0100
90#define PHY_AN_AD_100BASE_TX_HALF_DUPLEX 0x0080
91#define PHY_AN_AD_10BASE_T_FULL_DUPLEX 0x0040
92#define PHY_AN_AD_10BASE_T_HALF_DUPLEX 0x0020
93#define PHY_AN_AD_SELECTOR_FIELD 0x0001
94
95#define PHY_AN_STATUS_REGISTER 0x05
96
97#define PHY_AN_STATUS_100BASE_T4 0x0200
98#define PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX 0x0100
99#define PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX 0x0080
100#define PHY_AN_STATUS_10BASE_T_FULL_DUPLEX 0x0040
101#define PHY_AN_STATUS_10BASE_T_HALF_DUPLEX 0x0020
102
103static void phy_write_bit(bool_t bit);
104static void phy_release_bus();
105static bool_t phy_read_bit();
106static void phy_single_rel_bus();
107
108void phy_reset(uint8_t phy_addr)
109{
110#ifndef _MSC_VER
111 /* PHYのリセット */
112 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_RESET);
113
114 /* 500ms待
115つ */
116 /* tslp_tsk(500); 不要? */
117
118 /* リセット完了の確認 */
119 while((phy_read_reg(phy_addr, PHY_CONTROL_REGISTER) & PHY_CONTROL_RESET) != 0)
120 tslp_tsk(1);
121#endif
122}
123
124enum phy_mode_t phy_initialize(uint8_t phy_addr)
125{
126 uint_t result = 0;
127 uint16_t status;
128#ifndef _MSC_VER
129 /* リンク完了の確認 */
130 while((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_LINK_STATUS) == 0)
131 tslp_tsk(1);
132
133 /* オートネゴシエーションのお知らせを有効に設定 */
134 phy_write_reg(phy_addr, PHY_AN_ADVERTISEMENT_REGISTER,
135 PHY_AN_AD_100BASE_T4 | PHY_AN_AD_100BASE_TX_FULL_DUPLEX | PHY_AN_AD_100BASE_TX_HALF_DUPLEX
136 | PHY_AN_AD_10BASE_T_FULL_DUPLEX | PHY_AN_AD_10BASE_T_HALF_DUPLEX | PHY_AN_AD_SELECTOR_FIELD);
137
138 /* オートネゴシエーションを有効に設定 */
139 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_SPEED_SELECT | PHY_CONTROL_A_N_ENABLE);
140
141 /* オートネゴシエーション完了の確認 */
142 while((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_A_N_COMPLETE) == 0)
143 tslp_tsk(1);
144
145 status = phy_read_reg(phy_addr, PHY_AN_STATUS_REGISTER);
146
147 if ((status & (PHY_AN_STATUS_10BASE_T_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX)) != 0)
148 result |= 0x01;
149
150 if ((status & (PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX)) != 0)
151 result |= 0x02;
152#endif
153 return (enum phy_mode_t)result;
154}
155
156bool_t phy_is_link(uint8_t phy_addr)
157{
158#ifndef _MSC_VER
159 /* リンクの確認 */
160 return (phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_LINK_STATUS) == 0;
161#else
162 return true;
163#endif
164}
165
166uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
167{
168 uint16_t result = 0, bit;
169 int i;
170
171 /* PRE :32個の連続した1b */
172 for (i = 0; i < 32; i++)
173 phy_write_bit(true);
174
175 /* ST :フレームのå…
176ˆé ­ã‚’示す01bのライト */
177 phy_write_bit(false);
178 phy_write_bit(true);
179
180 /* OP :アクセス種別を示すコードのライト */
181 phy_write_bit(true);
182 phy_write_bit(false);
183
184 /* PHYAD :PHY-LSIのアドレスが1番の場合、00001bをライト(MSB から順次ライト)。 */
185 phy_write_bit((phy_addr & 0x10) != 0);
186 phy_write_bit((phy_addr & 0x08) != 0);
187 phy_write_bit((phy_addr & 0x04) != 0);
188 phy_write_bit((phy_addr & 0x02) != 0);
189 phy_write_bit((phy_addr & 0x01) != 0);
190
191 /* REGAD :レジスタアドレスが1番の場合、00001bをライト(MSBから順次ライト)。 */
192 phy_write_bit((reg_addr & 0x10) != 0);
193 phy_write_bit((reg_addr & 0x08) != 0);
194 phy_write_bit((reg_addr & 0x04) != 0);
195 phy_write_bit((reg_addr & 0x02) != 0);
196 phy_write_bit((reg_addr & 0x01) != 0);
197
198 /* TA :MII/RMIIインタフェース上でデータの送信å…
199ƒã‚’切り替える時間 */
200 /* 「バス解放」(Z0と表記)を行う */
201 phy_release_bus();
202
203 /* DATA :16ビットのデータ。MSBから順次リード */
204 for (bit = 0x8000; bit != 0; bit >>= 1) {
205 if(phy_read_bit())
206 result |= bit;
207 }
208
209 /* IDLE :次のMII管理フォーマットå…
210¥åŠ›ã¾ã§ã®å¾…
211機時間 */
212 /* すでにTA時にバス解放済みであり制御不要 */
213 phy_release_bus();
214
215 return result;
216}
217
218void phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_data)
219{
220 int i;
221 uint16_t bit;
222
223 /* PRE :32個の連続した1b */
224 for (i = 0; i < 32; i++)
225 phy_write_bit(true);
226
227 /* ST :フレームのå…
228ˆé ­ã‚’示す01bのライト */
229 phy_write_bit(false);
230 phy_write_bit(true);
231
232 /* OP :アクセス種別を示すコードのライト */
233 phy_write_bit(false);
234 phy_write_bit(true);
235
236 /* PHYAD :PHY-LSIのアドレスが1番の場合、00001bをライト(MSB から順次ライト)。 */
237 phy_write_bit((phy_addr & 0x10) != 0);
238 phy_write_bit((phy_addr & 0x08) != 0);
239 phy_write_bit((phy_addr & 0x04) != 0);
240 phy_write_bit((phy_addr & 0x02) != 0);
241 phy_write_bit((phy_addr & 0x01) != 0);
242
243 /* REGAD :レジスタアドレスが1番の場合、00001bをライト(MSBから順次ライト)。 */
244 phy_write_bit((reg_addr & 0x10) != 0);
245 phy_write_bit((reg_addr & 0x08) != 0);
246 phy_write_bit((reg_addr & 0x04) != 0);
247 phy_write_bit((reg_addr & 0x02) != 0);
248 phy_write_bit((reg_addr & 0x01) != 0);
249
250 /* TA :MII/RMIIインタフェース上でデータの送信å…
251ƒã‚’切り替える時間 */
252 /* 10bをライト */
253 phy_write_bit(true);
254 phy_write_bit(false);
255
256 /* DATA :16ビットのデータ。MSBから順次ライト */
257 for (bit = 0x8000; bit != 0; bit >>= 1) {
258 phy_write_bit((reg_data & bit) != 0);
259 }
260
261 /* IDLE :次のMII管理フォーマットå…
262¥åŠ›ã¾ã§ã®å¾…
263機時間 */
264 /* 「単独バス解放」(Xと表記)を行う */
265 phy_single_rel_bus();
266}
267
268#define ETHERC_PIR_WAIT 4
269
270/*
271 * 1 ビットデータのライト
272 */
273static void phy_write_bit(bool_t bit)
274{
275 int i;
276 uint32_t data = bit ? ETHERC_PIR_MDO : 0;
277
278 /* PHY部インタフェースレジスタへのライト */
279 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
280
281 for(i = ETHERC_PIR_WAIT; i > 0; i--);
282
283 /* PHY部インタフェースレジスタへのライト */
284 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | ETHERC_PIR_MDC);
285
286 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
287
288 /* PHY部インタフェースレジスタへのライト */
289 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
290
291 for(i = ETHERC_PIR_WAIT; i > 0; i--);
292}
293
294/*
295 * バス解放
296 */
297static void phy_release_bus()
298{
299 int i;
300
301 /* PHY部インタフェースレジスタへのライト */
302 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
303
304 for(i = ETHERC_PIR_WAIT; i > 0; i--);
305
306 /* PHY部インタフェースレジスタへのライト */
307 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
308
309 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
310
311 /* PHY部インタフェースレジスタへのライト */
312 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
313
314 for(i = ETHERC_PIR_WAIT; i > 0; i--);
315}
316
317/*
318 * 1 ビットデータのリード
319 */
320static bool_t phy_read_bit()
321{
322 bool_t bit;
323 int i;
324
325 for(i = ETHERC_PIR_WAIT; i > 0; i--);
326
327 /* PHY部インタフェースレジスタへのライト */
328 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
329
330 for(i = ETHERC_PIR_WAIT; i > 0; i--);
331
332 /* PHY部インタフェースレジスタへのライト */
333 bit = (sil_rew_mem(ETHERC_PIR) & ETHERC_PIR_MDI) != 0;
334
335 for(i = ETHERC_PIR_WAIT; i > 0; i--);
336
337 /* PHY部インタフェースレジスタへのライト */
338 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
339
340 for(i = ETHERC_PIR_WAIT; i > 0; i--);
341
342 return bit;
343}
344
345/*
346 * 単独バス解放
347 */
348static void phy_single_rel_bus()
349{
350 int i;
351
352 for(i = ETHERC_PIR_WAIT; i > 0; i--);
353
354 /* PHY部インタフェースレジスタへのライト */
355 sil_wrw_mem(ETHERC_PIR, ETHERC_PIR_MMD | ETHERC_PIR_MDC);
356
357 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
358
359 /* PHY部インタフェースレジスタへのライト */
360 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
361
362 for(i = ETHERC_PIR_WAIT; i > 0; i--);
363}
Note: See TracBrowser for help on using the repository browser.