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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
开发板:E9(飞思卡尔的imx6q主控)
5 w( c& q! ~) c  P
6 c9 \3 U6 J7 o内核:Linux 3.0.35) Q: c4 E. n$ L8 |
4 `7 h% Z/ n0 ]
PC OS:Ubuntu 11.04
# ]3 f' t) }9 Q( f) C7 L9 q9 @8 H" _6 C# [. ^. S: L# @! q- N

6 o" L3 j8 ^( a) Z' z  K% b' C! d' B) B7 c: k
本文对ENC28J60模块的驱动移植进行简单梳理。该模块购于淘宝。$ b$ Z% f$ r+ j& H/ _" N: @% |1 M
2 t; d' ~) \2 G& i( @: `) _( [
按照一般移植要素,有如下几个步骤:
* v7 B. b! u0 d) O( ^. [, m# h, V: J& S/ S- n% F
1. 按照各引脚所对应的功能进行初始化操作。
/ K& q% P& D+ j2 Q5 B. T2 f$ z& f
, h) M8 \' F( O, Z, p7 f2. 确定总线类型,在bsp中注册相应的主控制器信息。) J. o4 M) g& V( Y% E7 `

* ?2 l+ `" K9 w% N; k7 q3.在bsp中添加设备信息。
( i4 W* I" [& c/ n
! D2 g0 n5 Z8 X9 O4. 配置内核,打开设备配置选项。0 @# C2 l! Z% D& \: I
4 X# A( ?  ~2 K- `6 O1 c! I5 y; \0 k4 \
8 m# Z& ^3 g5 |# E) E

3 N! Z& Z, Y  r  j  @1. 硬件连线方式
& u- F" f% e$ X, F    IMX6开发板                        ENC28J60) x) T1 [$ e# X/ M& U- h- o* c: ?

! `, X, M9 \0 a* k; n* \CSPI2_CLK        --->               SCK
( l% o! D# E; N' ^9 G7 V7 g  Y) Y9 s- R4 `6 i) u9 D. J. ]$ v! {
CSPI2_MISO      <---                 SO8 Z7 S2 F8 ^7 S$ `3 w, k+ \

' j, H* y( o9 }, g+ r+ v2 r0 n1 {5 L) RCSPI2_MOSI      --->                  SI& I  r: j5 l3 f- n4 }0 U
! d0 t7 V- r5 C: Q
CSPI_CS0          --->                 CS  |, G. m9 b+ Q9 D  T* \! v+ A% c

! m. o, O1 a2 L: T3 @EIM_D21            <---                  INT
6 _+ c  o' i- `& V- i9 Q7 v% S. k  K
VCC  3.3v             --->                VCC( C6 ^5 E, e: `  ?1 t
3 d4 o2 E' K& T5 B" }% _
GND                     -->                 GND
7 r) B1 f* E* @4 j. G0 `6 j' N/ p! ]2 n9 y6 E

4 ]" v) B0 X3 |6 X/ q
' R. b; ?2 [0 C) Q; R' F0 _0 D, F* @: k* ?( Q/ Q6 l" G* K
2. 初始化引脚& v0 }) [3 _8 L8 d) l
从硬件连线方式可以看出,SPI总线使用的是imx6的SPI2控制器,同时额外需要一个GPIO作为中断引脚。9 q3 F; O  P( k8 E9 F: ^' V

. o6 @. s) [0 a# X在原文件arch/ARM/mach-mx6/board-mx6q_sabrESD.h的数组mx6q_sabresd_pads数组中添加如下内容:
+ W/ ~) R0 k+ H% w6 h) P( I0 U) G: I* O# e
        /* ECSPI2*/
2 r( D0 N* E4 X2 J! A; \        MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
' [+ [  B" ]! L( u        MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,
, q2 q$ M! T: s6 x' i        MX6Q_PAD_EIM_OE__ECSPI2_MISO,
! K6 E+ h: V. U# B* T: o- U# E        MX6Q_PAD_CSI0_DAT11__GPIO_5_29,       
( V. g6 }8 K9 v9 d; u' G        //MX6Q_PAD_EIM_D17__GPIO_3_17,9 v, C) Q2 P2 O0 ^6 i* D

5 `  J. J1 ~4 }& I! q8 Y7 G        MX6Q_PAD_EIM_D21__GPIO_3_21,  /* gpio interrupt for enc2860j */9 A& T9 z/ `' z8 Z/ V

! f$ b& O0 e- M1 w) Z  v/ t, r- X! f) C3. 注册SPI控制器和SPI板级设备3 d& p* G- t: j& ~" q
由于ENC28J60使用SPI总线,因此,在注册板级设备设备前,需要弄SPI的一些参数。
* j5 H& e2 [2 s  |* g- {8 Q' n) @* K' I+ Q; L" j1 `( R. W
ENC28J60使用SPI模式0进行传输,最大速率为10Mbps。
9 i* W/ K4 R6 t( y# T+ A
8 R  X1 p8 y/ J2 t! e4 J' }% \/ k( Z% N5 d在原文件arch/arm/mach-mx6/board-mx6q_sabresd.c中添加如下结构体的声明:" [; H6 ?3 s# c2 o( k8 E

" {- l3 z: x! Y/* Following is added by Jone Yim for enc28j60 */  T) n6 s- v/ C: d3 I
#define SABRESD_ECSPI2_CS0      IMX_GPIO_NR(5, 29)    /* CSPI2_CS0 */
; I( g1 U* [: `! Z- ]#define ENC28J60_INTERRUPT_GPIO IMX_GPIO_NR(3, 21)    /* EIM_D21 */
* C5 d" \. r0 q2 O& z1 |; y2 o
  E  l3 o' ?0 t9 V8 `/ m' B! istatic int mx6q_sabresd_spi2_cs[] = {: f" C  ^' N0 D0 J- o* T
        SABRESD_ECSPI2_CS0,  Z# J* l$ Z+ {6 `( O
};
0 |7 f) S6 K# p( p
$ k- T2 A1 ?+ b+ ?! d' [static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {4 o: J& g+ G% a$ j9 b1 l- g
        .chipselect     = mx6q_sabresd_spi2_cs,
3 y  s% m, V9 |) n        .num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),
  C- i1 [8 s: E6 ?) }! f$ P, u3 k};
; _8 f; a6 i9 h, J  |
. a+ g$ A8 W+ U6 {5 ?, L! Nstatic struct spi_board_info mx6_sabresd_spi2_board[]={
5 z9 M; O: C6 ~, ]6 c  ]6 d: Y   [0] = {
/ c9 ^9 ?$ k0 @% B( s, o% {             .modalias = "enc28j60",
& u1 Z" @0 R5 T# e$ A             .bus_num = 1,
0 t) ~3 a2 |! }             .chip_select = 0,
* \% }& B' N; S& r2 L             .max_speed_hz = 5000 * 1000,2 G7 S* E6 K+ J8 @5 B
             .mode = SPI_MODE_0,4 v# o8 ^; y0 W4 q3 M4 Q
    },7 D, t; b. x" I3 P' w  ?

4 q+ _8 m8 v8 e+ \};8 }6 m  s3 E/ Q& U

0 e: t; i5 f* O5 H' Y* o7 |/ h3 g8 w0 q/ ?+ R! D* v
首先通过宏定义了CS和INT所使用的引脚号,并定义了SPI板级设备。
! t% W% m1 \' }. p4 s; |; W
9 A7 {) Q* ^% K7 d, h* P接下来我们需要注册该SPI板级设备信息到内核中。
) W6 V5 a9 }; ?5 W% c4 d8 g4 _" n  V% D+ ]7 ~* G" v+ R
在同一文件下的mx6_sabresd_board_init函数中添加如下代码:$ u+ f4 F" o: M9 g6 {. j& W

/ z% y2 x8 ]) Y/ O( J/ V/* Following is added by Jone Yim for enc28j60 */
- f' W2 O% a/ I0 a7 T9 a        imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data); /*using ecspi2*/
( _  }! k$ S& n8 y' e* i, i* {; Y        * R1 V% s. G, O  W# L
        ret = gpio_request(ENC28J60_INTERRUPT_GPIO, "ENC28J60-int");, \/ o* l: U" d/ i$ P' J7 q5 ?
        if (ret) {
" d) e$ x- o8 q3 F3 E' H* E                printk(KERN_ERR"request ENC28J60-int error!!\n");
& F* {6 L& I* ?6 ^1 U. q        }else{
. [4 y; J/ B# g                gpio_direction_input(ENC28J60_INTERRUPT_GPIO);
0 Z, A, H# C( x# X1 v6 O6 i               
0 I3 s+ _2 |  Y8 J" t                //printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);7 ^2 R4 @4 l. a) v1 f, A
                irq = gpio_to_irq(ENC28J60_INTERRUPT_GPIO);
4 x7 p3 p7 w) ~6 u                if(irq < 0){
9 U8 [, f- o; u8 l. x6 l, ^                        printk(KERN_ERR"claim gpio irq error!!\n");
0 O' H0 ~. e* F: h0 o                }else{
' z0 v$ x1 t) q                        printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);
# v! o/ g  ~  I' H                        mx6_sabresd_spi2_board[0].irq = irq;
  o$ N( H& S9 e: h" D, w                        irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);& U( N( m4 E" y" g: Y5 I6 e7 C0 x
                        spi_register_board_info(mx6_sabresd_spi2_board, ARRAY_SIZE(mx6_sabresd_spi2_board));  \9 K  Q5 t$ H" @
                }
! ^" _" M% a. H, D5 @9 k/ c6 n) D5 _        }) i+ l* t% M+ B- t$ s6 V$ \
首先注册SPI2控制器,然后在调用spi_register_board_info注册SPI板级设备信息之前,我们向系统申请了用于中断的GPIO引脚,并获取了其irq号,并将该irq号保存到SPI板级设备信息。
) |4 q. O" E& L4 R; B其次,我们需要设置GPIO的中断类型为下降沿中断,这跟datasheet里面描述的一致。这里提一句为什么要在这里设置中断类型,这是因为在ENC28J60驱动源码的probe方法中并未设置其中断类型,反而是有一段注释要求在bsp中设置中断类型。
: E9 S' {/ n, K" }& e! V+ W( w0 f% m- f. ], u2 h% C7 U
一切就绪,最后spi_register_board_info调用注册SPI板级设备信息。! [, e% h& R) F0 C# k' ?: }5 h/ B

& f0 l+ O+ D4 |3 a* a
: n3 G5 \8 C8 C6 S) x3 t9 k& [& v& D. Y  Z( w
4.配置内核( F2 ]0 u3 x& H7 _$ S/ N
" F, M0 Y) s4 S6 O" n

  S+ X; c6 Y' z配置完以后即可编译。
: W& M) P) [( b! z- @& h' S1 d  P  w3 Q: O

  {. `4 `1 |  g
3 a3 H9 P# l# p; }( m; V( ]5.验证4 p+ O- K/ e; E% L8 U) A0 B
系统启动后执行如下命令:
  ^, H6 c/ a, D2 y- \& o7 c* ]: B2 B; }" A; Q& S9 O7 z
ifconfig eth0 down   //关闭原有的网口# t. P2 ]- k' i" @
+ m2 n) d8 ]2 E& O
ifconfig eth1 up 192.168.0.116   //打开ENC28J60对应的网口并设置IP地址
: S7 \; g+ ?! e5 D" c2 e
+ u' _/ ~; j  [  U% z
! h; b2 C! [2 ]* B) R. \( t: a" T5 X) X' g* i; j- {8 O. u# `2 o
然后ping以下虚拟机试试:
& N  O0 i' j6 M0 B; `: K / c5 K7 V1 L8 b
+ q0 }0 t- Q  r7 D) L* l
+ |) j3 O: ^6 [4 B9 D
ping通了,至此大功告成。
& q2 e9 B2 v& @: A" }8 B; F) E! W: n( I$ ?# G3 d' Z

5 V* _( y8 U9 H9 V6 R' b8 s
0 f' N* W9 O5 X& W8 \9 k# O
$ [. @& M( k* D+ _4 [4 _: K; y
- G9 }9 a6 k- O7 f3 R6 B' Z) M. Z, X

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 23:05 , Processed in 0.171875 second(s), 27 queries , Gzip On.

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

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

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