找回密码
 注册
关于网站域名变更的通知
查看: 385|回复: 1
打印 上一主题 下一主题

Linux驱动移植——ENC28J60以太网控制器

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-5-27 16:17 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
开发板:E9(飞思卡尔的imx6q主控)
1 _# Z  e  l' e* t* {$ r
& l6 Y- e' p/ q8 b) X* H内核:Linux 3.0.35
. t; a2 n( w& F! {( j# W
, Q+ S/ I  g: U4 i0 `PC OS:Ubuntu 11.04
" ~0 ]3 D1 v% w$ w4 ~" f( W3 x2 g- y, `& l" M- k
& Y0 }8 N; v% [& H
8 X$ ?- T4 p  K8 }5 c; y( C$ Y' n
本文对ENC28J60模块的驱动移植进行简单梳理。该模块购于淘宝。+ g  i( M, l9 Z, e* L/ o7 h2 b

( L$ e$ t& X/ _7 _( Z按照一般移植要素,有如下几个步骤:
+ b9 R( D- ?; G8 z$ }+ c2 D6 [/ u/ i# M9 }( {
1. 按照各引脚所对应的功能进行初始化操作。
+ Y+ c* Q" L* d9 T+ i
  u( M9 |7 ^; ~4 ^2. 确定总线类型,在bsp中注册相应的主控制器信息。0 B, [0 r7 H7 @3 {
! k( N) w9 F8 U% X  @
3.在bsp中添加设备信息。
* z9 e9 l4 o; k. X, T7 J# @) x* c& g9 F
$ e5 E3 d4 f5 Q3 O4. 配置内核,打开设备配置选项。
+ z8 X3 z& _8 T2 i% p& B. l/ D* Y5 X& f
6 Z* v3 F* q# @

3 `' F6 \0 M& j( w4 D1. 硬件连线方式( ^# u, R$ e4 ?
    IMX6开发板                        ENC28J60
) Q% f0 W& S4 w  H" p7 G9 }  ], I! o0 @2 C# U3 [2 n8 f- A
CSPI2_CLK        --->               SCK+ z& O( K. g- U/ ~" f4 M- R' \: H" [
9 J5 Q$ ]/ Y, T5 S( D
CSPI2_MISO      <---                 SO
1 J1 ?1 f4 D# i: |
: Q/ ?+ j1 H7 f. UCSPI2_MOSI      --->                  SI( z; e4 Q9 O6 k. R! k* h

; _+ R' Z( x. x% ?9 l5 e$ BCSPI_CS0          --->                 CS
- w% M5 q# b$ e! |* {# q  B
$ q9 H* X! B( C$ V  a( m  vEIM_D21            <---                  INT: U1 Z1 I% y2 R
' ]* C) k% J$ Q# ^1 Q
VCC  3.3v             --->                VCC; e1 _! u, Z% E, A4 e  T

) L$ ]* m# t  E$ U! n5 zGND                     -->                 GND
  q- v  \' I5 F+ V+ J
5 s; A9 u0 T) |, c7 M' a& J8 S9 J+ l3 Q' S

) o5 C( K, G, `; n: l1 C  s" t  o0 A! d3 B
2. 初始化引脚
/ [5 U, V# z. u6 }  h  ]从硬件连线方式可以看出,SPI总线使用的是imx6的SPI2控制器,同时额外需要一个GPIO作为中断引脚。0 K$ u* g3 h8 h7 c; E! [

3 z& i6 `  y7 l* D$ j; {2 D在原文件arch/ARM/mach-mx6/board-mx6q_sabrESD.h的数组mx6q_sabresd_pads数组中添加如下内容:# v2 f! Z* _$ v" ^

2 e8 h/ H) g+ q, V        /* ECSPI2*/
6 M8 A+ w4 E& I        MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
0 V) Z+ H& K; _5 d5 x        MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,! B0 [. d, m; `% [6 g
        MX6Q_PAD_EIM_OE__ECSPI2_MISO,' J1 G$ l4 @$ t/ D
        MX6Q_PAD_CSI0_DAT11__GPIO_5_29,       
) K6 j( T" j: v  `& d" n% ~) T2 G  V        //MX6Q_PAD_EIM_D17__GPIO_3_17,
* [" D- t/ U" g( v& p5 f- w/ |) h/ c! s! m9 n. _
        MX6Q_PAD_EIM_D21__GPIO_3_21,  /* gpio interrupt for enc2860j *// v2 }! E; h6 w- A7 |' c6 L' `! S7 L' v$ A
* t* |1 ~2 q5 m2 `
3. 注册SPI控制器和SPI板级设备2 w  a4 l& \: L; ]9 J( c
由于ENC28J60使用SPI总线,因此,在注册板级设备设备前,需要弄SPI的一些参数。4 G0 |) ~' l- M4 K1 l. E, Z0 k8 q  C& x

  E+ `, j' n" v: ^ENC28J60使用SPI模式0进行传输,最大速率为10Mbps。
% I+ I: ?. n8 E9 c! n
0 v3 X" S$ u6 O3 n6 ?% j在原文件arch/arm/mach-mx6/board-mx6q_sabresd.c中添加如下结构体的声明:
, |( r' x2 }" h# G6 F! W* f$ b: |
/* Following is added by Jone Yim for enc28j60 */0 M4 N8 z- b: a9 R4 W. x9 y& H' I
#define SABRESD_ECSPI2_CS0      IMX_GPIO_NR(5, 29)    /* CSPI2_CS0 */& L. \# V$ r' r% b$ X  C1 T
#define ENC28J60_INTERRUPT_GPIO IMX_GPIO_NR(3, 21)    /* EIM_D21 */
$ R* a" l. t8 @8 s- j# L& w% e9 }4 K0 }. O* h: Z8 ^6 f1 b
static int mx6q_sabresd_spi2_cs[] = {
4 N8 S" q$ g8 z6 z        SABRESD_ECSPI2_CS0,$ j9 s% z+ N5 Y. u4 t0 i
};
6 q5 T2 J, d3 W6 B0 Z
, u4 Q4 S7 g# c; t% _! e- `& B% Wstatic const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {; |6 {8 v$ k4 E
        .chipselect     = mx6q_sabresd_spi2_cs,
3 A+ D) Q$ Q$ J9 `9 N        .num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),
& J% G8 x9 s! e1 |8 E};
# O7 K( A; [% C# y% K/ x- U6 P
+ T1 \" M5 W' H2 V$ Y9 R" l' u- g! o0 ^static struct spi_board_info mx6_sabresd_spi2_board[]={  Z1 p4 G! u5 W- t- _! d7 B" \
   [0] = {! }: x) u* X( s3 x' E1 `
             .modalias = "enc28j60",
) R& a3 _/ ]% B: E& d9 I3 V8 Q             .bus_num = 1,! ~% E( C2 ^7 d; t' M( a
             .chip_select = 0,
% C! b7 c; u. d             .max_speed_hz = 5000 * 1000,3 l# w- ]4 m8 r6 C/ L2 x: d  ]
             .mode = SPI_MODE_0,. Q& O0 `# }* M/ ~& {' X- h
    },/ `% E; ]" M$ \8 I  `
, [# ]4 J' U6 [9 h0 d4 _4 Q0 y
};
6 W. C+ {- ]& r, H1 N3 m1 d8 x/ W/ c0 f% m7 Z! O. v! D# P

# v9 J3 G  s: q3 R" z- o) n; j. U首先通过宏定义了CS和INT所使用的引脚号,并定义了SPI板级设备。
- Y& P/ u2 i: ^5 @; K2 ?4 P& S. r" z6 x9 d% `9 Z
接下来我们需要注册该SPI板级设备信息到内核中。
1 R( O, U$ N( q' J$ z  b; {
# W' K/ I* h7 p/ R2 q4 Z% X) l在同一文件下的mx6_sabresd_board_init函数中添加如下代码:
9 j' y4 F* n& d: C3 S: Q& ?8 G2 x: I5 v  O2 |# X% S4 V
/* Following is added by Jone Yim for enc28j60 */5 n# Y* I% g. g
        imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data); /*using ecspi2*/
, k; @+ T( a! @: R& m; T& R0 j       
, y4 Z+ c) U* P        ret = gpio_request(ENC28J60_INTERRUPT_GPIO, "ENC28J60-int");
- r2 @: u/ E  Z2 h& j  {" d6 j        if (ret) {$ \" {3 r' Q0 }
                printk(KERN_ERR"request ENC28J60-int error!!\n");0 z9 [- m) \% o* v5 S' P
        }else{. D, h4 u0 c& b; k2 J
                gpio_direction_input(ENC28J60_INTERRUPT_GPIO);
. v+ [/ {! w& M                ; H, j9 X3 \5 n7 l" \
                //printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);
" c7 s9 _9 ^: ]: t+ u0 k                irq = gpio_to_irq(ENC28J60_INTERRUPT_GPIO);
% [5 S' v, P) \& o! a                if(irq < 0){9 x3 C  @! m5 b5 w* W- t
                        printk(KERN_ERR"claim gpio irq error!!\n");, \0 y& }# S# U! _
                }else{
& ?+ C2 L  |, N+ `                        printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);  l% D6 \  k* z* \1 y4 Z' A6 n; g
                        mx6_sabresd_spi2_board[0].irq = irq;: y1 S% S4 ?- Q5 x' f5 ?7 ~
                        irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
+ z$ h' K2 c+ x4 Q7 x                        spi_register_board_info(mx6_sabresd_spi2_board, ARRAY_SIZE(mx6_sabresd_spi2_board));2 }' Y3 j% I4 V- ~0 ~% |5 @, u
                }
5 s4 r' f2 t# C/ T0 p3 _        }
9 W" M& {6 U0 H5 i; T5 w6 Y. k首先注册SPI2控制器,然后在调用spi_register_board_info注册SPI板级设备信息之前,我们向系统申请了用于中断的GPIO引脚,并获取了其irq号,并将该irq号保存到SPI板级设备信息。
0 F/ [8 Y  n  o, H& r其次,我们需要设置GPIO的中断类型为下降沿中断,这跟datasheet里面描述的一致。这里提一句为什么要在这里设置中断类型,这是因为在ENC28J60驱动源码的probe方法中并未设置其中断类型,反而是有一段注释要求在bsp中设置中断类型。3 S- Y$ g7 y7 h9 |, M, x! E
# X5 o5 m. r8 `8 P& k
一切就绪,最后spi_register_board_info调用注册SPI板级设备信息。) W1 {, p/ D- n- v5 M

5 X7 d+ v! P) {  V4 e, k% m* {
. M1 m' c( i4 q. @, o2 B/ H  V0 h2 e* S% b# Q9 I% D- `
4.配置内核
4 A" L$ c, M, z9 A+ b
% ^! z% K$ Z6 F; ^& g  j* y4 b: [% N
, A+ M/ z' b/ g3 T+ k  Z5 l8 X4 m: A配置完以后即可编译。
3 ^9 V/ B: y0 b- Q
2 x# w4 S" u8 n& f) Y" {- w" C. h( e
% b& w$ m9 x6 F. l' V
5.验证
) d2 N" G- O2 e4 f* F: |+ f; }系统启动后执行如下命令:) W" c5 g* v, t* X" S7 T
/ u7 g5 u, w8 l% D+ d1 k* c: Q
ifconfig eth0 down   //关闭原有的网口$ k& N1 `. F6 y) t: S. m% x; k+ @
6 D7 Y0 t$ L% p
ifconfig eth1 up 192.168.0.116   //打开ENC28J60对应的网口并设置IP地址# T2 c! T. Z& j5 J$ S0 [

9 z! F! I% W' J( ]) w/ @* V6 g
2 W* f% ^9 g5 L# g6 x
+ r% W3 _; j4 P! R! t/ W( g然后ping以下虚拟机试试:* V3 T4 V' h. l) P! c7 j9 _

0 Q: w" ^) E7 X: }4 L$ a/ M; P( k. @5 O

; d0 T* D) `  ?' E# D8 }- Qping通了,至此大功告成。
9 O1 H" D1 }  Z* V2 O3 A( v% H, I3 h6 @( k

, ~5 [  z4 c; ~8 X- j7 a; v' D, v; j1 G* A( f9 p
' S1 t5 Z" `' m+ d, U
9 Y, v3 k/ U/ t- G$ D$ u  F
9 B% U- G' s* Z3 M

该用户从未签到

2#
发表于 2020-5-27 17:05 | 只看该作者
ENC28J60以太网控制器
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-26 08:09 , Processed in 0.187500 second(s), 27 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表