source: uKadecot/trunk/uip/target/if_rx62n/if_rx62n.c@ 158

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

インクルードのパス指定をContikiに合わせ変更。
整数型の型名をContikiに合わせ変更。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr; charset=SHIFT_JIS
File size: 10.8 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: if_rx62n.c 158 2016-02-20 13:43:32Z coas-nagasima $
36 */
37
38#define CAST(type, val) ((type)(val))
39
40#include <kernel.h>
41#include <sil.h>
42#include <t_syslog.h>
43#include <string.h>
44#include "kernel_cfg.h"
45#include "kernel/kernel_impl.h"
46#include "uip_target_config.h"
47#include "net/ipv4/uip_arp.h"
48#include "if_rx62n.h"
49#include "ether_phy.h"
50
51extern uint8_t mac_addr[ETHER_ADDR_LEN];
52
53/*
54 * ネットワークインタフェースに依存するソフトウェア情報
55 */
56
57typedef struct t_rx62n_softc {
58 T_RX62N_TX_DESC *tx_write;
59 T_RX62N_RX_DESC *rx_read;
60 PHY_STATE_T state;
61} T_RX62N_SOFTC;
62
63/*
64 * ネットワークインタフェースのソフトウェア情報
65 */
66
67/* ネットワークインタフェースに依存するソフトウェア情報 */
68
69static T_RX62N_SOFTC rx62n_softc;
70
71typedef struct t_rx62n_buf {
72 uint8_t rx_buff[NUM_IF_RX62N_RXBUF][32 * ((IF_RX62N_BUF_PAGE_SIZE + 31) / 32)];
73 uint8_t tx_buff[NUM_IF_RX62N_TXBUF][32 * ((IF_RX62N_BUF_PAGE_SIZE + 31) / 32)];
74 T_RX62N_RX_DESC rx_desc[NUM_IF_RX62N_RXBUF];
75 T_RX62N_TX_DESC tx_desc[NUM_IF_RX62N_TXBUF];
76} T_RX62N_BUF;
77
78#if defined(__RX)
79#pragma section ETH_MEMORY
80#endif
81T_RX62N_BUF rx62n_buf;
82#if defined(__RX)
83#pragma section
84#endif
85
86/* ネットワークインタフェースに依存しないソフトウェア情報 */
87
88T_IF_SOFTC if_softc = {
89// {0,}, /* ネットワークインタフェースのアドレス */
90// 0, /* 送信タイムアウト */
91 &rx62n_softc, /* ディバイス依存のソフトウェア情報 */
92};
93
94/*
95 * 局所変数
96 */
97
98static void rx62n_stop (T_RX62N_SOFTC *sc);
99static void rx62n_init_sub (T_IF_SOFTC *ic);
100static void rx62n_set_ecmr (T_IF_SOFTC *ic, PHY_MODE_T mode);
101
102/*
103 * rx62n_stop -- ネットワークインタフェースを停止する。
104 *
105 * 注意: NIC 割り込み禁止状態で呼び出すこと。
106 */
107
108static void
109rx62n_stop (T_RX62N_SOFTC *sc)
110{
111 /* 動作モードクリア */
112 sil_wrw_mem(ETHERC_ECMR, 0x00000000);
113}
114
115/*
116 * rx62n_init_sub -- ネットワークインタフェースの初期化
117 *
118 * 注意: NIC 割り込み禁止状態で呼び出すこと。
119 */
120
121static void
122rx62n_init_sub (T_IF_SOFTC *ic)
123{
124 int i;
125 PHY_STATE_T state = PHY_STATE_UNINIT;
126
127 /* MAC部ソフトウエア・リセット */
128 sil_wrw_mem(EDMAC_EDMR, sil_rew_mem(EDMAC_EDMR) | EDMAC_EDMR_SWR_BIT);
129
130 /* リセット完了待ち */
131 for (i = 0; i < 10000; i++) {
132 }
133
134 sil_wrw_mem(ETHERC_MAHR, ((uint32_t)mac_addr[0] << 24)
135 | ((uint32_t)mac_addr[1] << 16) | ((uint32_t)mac_addr[2] << 8 )
136 | (uint32_t)mac_addr[3]);
137 sil_wrw_mem(ETHERC_MALR, ((uint32_t)mac_addr[4] << 8 )
138 | (uint32_t)mac_addr[5]);
139
140 /* PHYリセット */
141 while((state = phy_reset(state, 0)) != PHY_STATE_RESET);
142 ic->sc->state = state;
143
144 /* Clear all ETHERC status BFR, PSRTO, LCHNG, MPD, ICD */
145 sil_wrw_mem(ETHERC_ECSR, 0x00000037);
146
147 /* リンク変化割り込み有効 */
148 sil_wrw_mem(ETHERC_ECSIPR, sil_rew_mem(ETHERC_ECSIPR) | ETHERC_ECSIPR_LCHNGIP);
149
150 /* Clear all ETHERC and EDMAC status bits */
151 sil_wrw_mem(EDMAC_EESR, 0x47FF0F9F);
152
153 /* 送受信割り込み有効 */
154 sil_wrw_mem(EDMAC_EESIPR, (EDMAC_EESIPR_TCIP | EDMAC_EESIPR_FRIP | EDMAC_EESIPR_RDEIP | EDMAC_EESIPR_FROFIP));
155
156 /* 受信フレーム長上限(バッファサイズ) */
157 sil_wrw_mem(ETHERC_RFLR, IF_RX62N_BUF_PAGE_SIZE);
158
159 /* 96ビット時間(初期値) */
160 sil_wrw_mem(ETHERC_IPGR, 0x00000014);
161
162 /* Set little endian mode */
163 sil_wrw_mem(EDMAC_EDMR, sil_rew_mem(EDMAC_EDMR) | EDMAC_EDMR_DE_BIT);
164
165 /* Initialize Rx descriptor list address */
166 sil_wrw_mem(EDMAC_RDLAR, (uint32_t)rx62n_buf.rx_desc);
167 /* Initialize Tx descriptor list address */
168 sil_wrw_mem(EDMAC_TDLAR, (uint32_t)rx62n_buf.tx_desc);
169 /* Copy-back status is RFE & TFE only */
170 sil_wrw_mem(EDMAC_TRSCER, 0x00000000);
171 /* Threshold of Tx_FIFO */
172 sil_wrw_mem(EDMAC_TFTR, 0x00000000);
173 /* Transmit fifo & receive fifo is 2048 bytes */
174 sil_wrw_mem(EDMAC_FDR, 0x00000707);
175 /* RR in EDRRR is under driver control */
176 sil_wrw_mem(EDMAC_RMCR, 0x00000001);
177
178 /* PHYの初期化を促す */
179 ic->link_pre = true;
180 ic->link_now = false;
181
182 /* ターゲット依存部の割込み初期化 */
183 rx62n_inter_init();
184}
185
186/*
187 * rx62n_set_ecmr -- ECMRレジスタの設定
188 */
189
190static void
191rx62n_set_ecmr (T_IF_SOFTC *ic, PHY_MODE_T mode)
192{
193 uint32_t ecmr;
194
195 ecmr = ETHERC_ECMR_RE | ETHERC_ECMR_TE/* | ETHERC_ECMR_PRM*/;
196
197 if ((mode & 0x01) != 0)
198 ecmr |= ETHERC_ECMR_DM;
199 if ((mode & 0x02) != 0)
200 ecmr |= ETHERC_ECMR_RTM;
201
202 /* 動作モード設定 */
203 sil_wrw_mem(ETHERC_ECMR, ecmr);
204}
205
206/*
207 * rx62n_reset -- ネットワークインタフェースをリセットする。
208 */
209
210void
211rx62n_reset (T_IF_SOFTC *ic)
212{
213 /* NIC からの割り込みを禁止する。*/
214 dis_int(INTNO_IF_RX62N_TRX);
215
216 rx62n_stop(ic->sc);
217 rx62n_init_sub(ic);
218
219 /* NIC からの割り込みを許可する。*/
220 ena_int(INTNO_IF_RX62N_TRX);
221}
222
223/*
224 * get_rx62n_softc -- ネットワークインタフェースのソフトウェア情報を返す。
225 */
226
227T_IF_SOFTC *
228rx62n_get_softc (void)
229{
230 return &if_softc;
231}
232
233/*
234 * rx62n_watchdog -- ネットワークインタフェースのワッチドッグタイムアウト
235 */
236
237void
238rx62n_watchdog (T_IF_SOFTC *ic)
239{
240 rx62n_reset(ic);
241}
242
243/*
244 * rx62n_probe -- ネットワークインタフェースの検出
245 */
246
247void
248rx62n_probe (T_IF_SOFTC *ic)
249{
250 /* ターゲット依存部のバスの初期化 */
251 rx62n_bus_init();
252
253 memcpy(uip_ethaddr.addr, mac_addr, sizeof(uip_ethaddr.addr));
254}
255
256/*
257 * rx62n_init -- ネットワークインタフェースの初期化
258 */
259
260void
261rx62n_init (T_IF_SOFTC *ic)
262{
263 T_RX62N_SOFTC *sc = ic->sc;
264 T_RX62N_TX_DESC *tdsc;
265 T_RX62N_RX_DESC *rdsc;
266 int i;
267
268 /* NIC からの割り込みを禁止する。*/
269 dis_int(INTNO_IF_RX62N_TRX);
270
271 tdsc = (T_RX62N_TX_DESC *)rx62n_buf.tx_desc;
272 sc->tx_write = tdsc;
273 for ( i=0 ; i < NUM_IF_RX62N_TXBUF ; i++ ) {
274 memset(tdsc, 0, sizeof(*tdsc));
275 tdsc->tbl = 0;
276 tdsc->tba = (uint32_t)&rx62n_buf.tx_buff[i];
277 tdsc++;
278 }
279 tdsc--;
280 tdsc->tdle = 1;
281
282 rdsc = (T_RX62N_RX_DESC *)rx62n_buf.rx_desc;
283 sc->rx_read = rdsc;
284 for ( i=0 ; i < NUM_IF_RX62N_RXBUF ; i++ ) {
285 memset(rdsc, 0, sizeof(*rdsc));
286 rdsc->rbl = IF_RX62N_BUF_PAGE_SIZE;
287 rdsc->rba = (uint32_t)&rx62n_buf.rx_buff[i];
288 rdsc->rfl = 0;
289 rdsc->ract = 1;
290 rdsc++;
291 }
292 rdsc--;
293 rdsc->rdle = 1;
294
295 /* rx62n_init 本体を呼び出す。*/
296 rx62n_init_sub(ic);
297
298 if (sil_rew_mem(EDMAC_EDRRR) == 0) {
299 sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
300 }
301
302 /* NIC からの割り込みを許可する。*/
303 ena_int(INTNO_IF_RX62N_TRX);
304}
305
306/*
307 * rx62n_link -- リンク状態の変化に対する処理
308 */
309bool_t
310rx62n_link(T_IF_SOFTC *ic)
311{
312 T_RX62N_SOFTC *sc = ic->sc;
313 PHY_MODE_T mode;
314
315 if(sc->state == PHY_STATE_NEGOTIATED){
316 ic->link_now = phy_is_link(0);
317 if(!ic->link_now)
318 sc->state = PHY_STATE_RESET;
319 return true;
320 }
321
322 /* PHYの初期化 */
323 sc->state = phy_initialize(sc->state, 0, &mode);
324 if(sc->state != PHY_STATE_NEGOTIATED){
325 return false;
326 }
327
328 /* ECMRレジスタの設定 */
329 rx62n_set_ecmr(ic, mode);
330 return true;
331}
332
333/*
334 * rx62n_read -- フレームの読み込み
335 */
336
337int
338rx62n_read (T_IF_SOFTC *ic, void **input)
339{
340 T_RX62N_SOFTC *sc = ic->sc;
341 T_RX62N_RX_DESC *desc;
342 uint16_t len;
343
344 if (ic->over_flow) {
345 ic->over_flow = false;
346 }
347
348 desc = sc->rx_read;
349
350 if (desc->ract != 0) {
351 return 0;
352 }
353
354 len = desc->rfl;
355 memcpy(*input, (void *)desc->rba, len);
356
357 desc->rfp = 0;
358 desc->ract = 1;
359
360 desc++;
361 if (desc == &rx62n_buf.rx_desc[NUM_IF_RX62N_RXBUF]) {
362 desc = rx62n_buf.rx_desc;
363 }
364 sc->rx_read = desc;
365
366 if (sil_rew_mem(EDMAC_EDRRR) == 0) {
367 sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
368 }
369
370 if ((ic->rxb_read == ic->rxb_write) && (desc->ract == 0))
371 ic->rxb_read--;
372
373 return len;
374}
375
376/*
377 * rx62n_start -- 送信フレームをバッファリングする。
378 */
379
380bool_t
381rx62n_start (T_IF_SOFTC *ic, void *output, int size)
382{
383 T_RX62N_SOFTC *sc = ic->sc;
384 T_RX62N_TX_DESC *desc, *next;
385 uint8_t *buf = NULL;
386 int32_t len, res, pos;
387 uint32_t tfp;
388
389 for ( res = size, pos = 0; res > 0; res -= len, pos += len ) {
390 desc = sc->tx_write;
391
392 if (desc->tact != 0) {
393 return false;
394 }
395
396 buf = (uint8_t *)desc->tba;
397
398 next = desc + 1;
399 if (next == &rx62n_buf.tx_desc[NUM_IF_RX62N_TXBUF]) {
400 next = rx62n_buf.tx_desc;
401 }
402 sc->tx_write = next;
403
404 len = res;
405 if ( len > IF_RX62N_BUF_PAGE_SIZE ) {
406 len = IF_RX62N_BUF_PAGE_SIZE;
407 tfp = 0x0;
408 }
409 else
410 tfp = 0x1;
411
412 if (pos == 0)
413 tfp |= 0x2;
414
415 memcpy(buf, (uint8_t *)output + pos, len);
416
417 desc->tbl = len;
418 desc->tfp = tfp;
419 desc->tact = 1;
420 }
421
422 if (sil_rew_mem(EDMAC_EDTRR) == 0) {
423 sil_wrw_mem(EDMAC_EDTRR, EDMAC_EDTRR_TR);
424 }
425
426 return true;
427}
428
429/*
430 * RX62N Ethernet Controler 送受信割り込みハンドラ
431 */
432
433void
434if_rx62n_trx_handler (void)
435{
436 T_IF_SOFTC *ic;
437 T_RX62N_SOFTC *sc;
438 uint32_t ecsr, eesr, psr;
439 bool_t acttsk = false;
440
441 i_begin_int(INTNO_IF_RX62N_TRX);
442
443 ic = &if_softc;
444 sc = ic->sc;
445
446 ecsr = sil_rew_mem(ETHERC_ECSR);
447
448 if (ecsr & ETHERC_ECSR_LCHNG) {
449 /* ETHERC部割り込み要因クリア */
450 sil_wrw_mem(ETHERC_ECSR, ETHERC_ECSR_LCHNG);
451
452 psr = sil_rew_mem(ETHERC_PSR);
453 ic->link_now = (psr & ETHERC_PSR_LMON) != 0;
454
455 /* リンク状態に変化あり */
456 if (ic->link_pre != ic->link_now) {
457 /* 受信割り込み処理 */
458 acttsk = true;
459 }
460 }
461
462 eesr = sil_rew_mem(EDMAC_EESR);
463
464 if (eesr & EDMAC_EESR_FR) {
465 /* DMA部割り込み要因クリア */
466 sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FR);
467
468 /* 受信割り込み処理 */
469 acttsk = true;
470 ic->rxb_write++;
471 }
472 if (eesr & EDMAC_EESR_TC) {
473 /* DMA部割り込み要因クリア */
474 sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_TC);
475
476 /* 送信割り込み処理 */
477 acttsk = true;
478 }
479 if (eesr & (EDMAC_EESR_FROF | EDMAC_EESR_RDE)) {
480 /* DMA部割り込み要因クリア */
481 sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FROF | EDMAC_EESR_RDE);
482
483 ic->over_flow = true;
484
485 /* 受信割り込み処理 */
486 acttsk = true;
487 ic->rxb_write++;
488 }
489
490 if(acttsk)
491 iact_tsk(UIP_TASK);
492
493 i_end_int(INTNO_IF_RX62N_TRX);
494}
Note: See TracBrowser for help on using the repository browser.