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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
开发板:E9(飞思卡尔的imx6q主控)
3 U" R, T) [# C5 Q% D# F4 r
9 M) w& q( v2 D3 X内核:Linux 3.0.35& M% ?% \  j! n$ l( j- H) U
/ L1 l0 P" O5 ~/ I
PC OS:Ubuntu 11.04! @" [3 i% [/ R# A( Q1 w
+ f4 m# u  f6 O) _1 C

0 ]3 \0 H2 a- S' Q' J$ |8 m+ E8 N! I9 k5 _$ p
本文对ENC28J60模块的驱动移植进行简单梳理。该模块购于淘宝。
7 X% t' {5 q4 `; w$ h8 j: B3 U) {# p3 @( P
按照一般移植要素,有如下几个步骤:' T- q* i6 F! f; d

! x: G6 N1 l6 O6 V1. 按照各引脚所对应的功能进行初始化操作。
1 \* }/ E" S% ^; h) F7 o& ^' `4 C; t" g. W; m. t
2. 确定总线类型,在bsp中注册相应的主控制器信息。
- O9 v! h: i& {, b# j
( u, U9 z7 g# R3.在bsp中添加设备信息。3 \/ e% W7 X5 E$ R  B
1 _  x  h. b0 N1 P& p; Z
4. 配置内核,打开设备配置选项。
) ?8 w) t" ]5 |6 S8 l& D0 \& [7 ~4 M/ {- H- Y6 I6 w  l7 F1 r5 ]

( {5 U$ I! U( M" i2 M* j6 z) \, _
  x5 t0 s4 Q2 o5 v1. 硬件连线方式$ ]$ W) p) v& k8 ^- I- C
    IMX6开发板                        ENC28J60
' P7 y( L0 W( i* `: ~% ?* i- ?- F# M( I4 d1 g
CSPI2_CLK        --->               SCK
) L( s& f% i! {3 D3 H* Y" L5 F9 f! w3 V0 W8 e% r% z8 [
CSPI2_MISO      <---                 SO( ~8 d& e. h8 |8 e! r1 ^
" O, L9 A8 ?' p/ d4 w5 Z  L
CSPI2_MOSI      --->                  SI- k" ]  I1 ^  c% u& s. J  K8 v6 R

. b5 c! Z  _+ n. iCSPI_CS0          --->                 CS3 B" V/ C4 n4 V8 h, V

( m- h9 l9 C, g' f: U0 sEIM_D21            <---                  INT
; T: a0 @5 {) e+ Y1 S; a
/ m, O; m, E1 f4 P4 dVCC  3.3v             --->                VCC
- I2 M2 X; ^3 z9 A, _, y5 y& o
; j# F$ Z3 @* Y& a- dGND                     -->                 GND
- B& a9 R! z& c8 x" c7 l0 M- D) V. t5 {( B; v# u; @0 y" w) P/ |+ ]

/ X! p3 P1 D# k( |& |/ ~* ~( G: x) s. A6 t2 \  _0 v  i7 \+ G
% U) r; r9 c$ V+ W
2. 初始化引脚0 M/ l/ \& W" @
从硬件连线方式可以看出,SPI总线使用的是imx6的SPI2控制器,同时额外需要一个GPIO作为中断引脚。
$ L0 N4 `4 ^% z$ o0 h" R( i( }3 T" l% w) e! U( w
在原文件arch/ARM/mach-mx6/board-mx6q_sabrESD.h的数组mx6q_sabresd_pads数组中添加如下内容:7 E/ Q& C# q5 Y

, l, `* u8 l! j6 I% b$ y0 n) \: B7 E        /* ECSPI2*/- H: s" u- ^( B% I( o7 t. r% f8 E
        MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,9 d6 V6 d; f$ k
        MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,7 K" Y$ j& D! W! z8 A$ ?( j, {$ p6 D
        MX6Q_PAD_EIM_OE__ECSPI2_MISO,0 [6 S, i' L- K) l; F& J
        MX6Q_PAD_CSI0_DAT11__GPIO_5_29,        $ |: s$ c: @5 m& n
        //MX6Q_PAD_EIM_D17__GPIO_3_17,
# G- ^: w3 R3 p1 I) g, S/ y+ F1 e" t% |3 g( ]
        MX6Q_PAD_EIM_D21__GPIO_3_21,  /* gpio interrupt for enc2860j */) L- H* X: ^1 v: n* }" v

0 c) Y7 e9 L0 ?# w) [3. 注册SPI控制器和SPI板级设备
) z5 X" k& p6 V) m: ^! n" i由于ENC28J60使用SPI总线,因此,在注册板级设备设备前,需要弄SPI的一些参数。! g( h2 P$ x" n; R" x

' F# p) s& ^; ~: V: ?ENC28J60使用SPI模式0进行传输,最大速率为10Mbps。/ n& F+ C3 C! g! g/ [
  g. ]3 k) ?) U5 j( m% \
在原文件arch/arm/mach-mx6/board-mx6q_sabresd.c中添加如下结构体的声明:6 O! w4 x% e% l4 i+ S9 T
2 a* i8 \, s4 u! S; q( v
/* Following is added by Jone Yim for enc28j60 */
) [, b+ r" K; Y% V8 }. T#define SABRESD_ECSPI2_CS0      IMX_GPIO_NR(5, 29)    /* CSPI2_CS0 */) j7 ]+ k4 {0 A; l6 g
#define ENC28J60_INTERRUPT_GPIO IMX_GPIO_NR(3, 21)    /* EIM_D21 */# B: d) S- S4 m* h: {) x

/ _' X- F$ s+ U) Ustatic int mx6q_sabresd_spi2_cs[] = {: y- V- k5 A% U% I
        SABRESD_ECSPI2_CS0,
& Q7 Y& |# V) p( l. g};' Y/ {" _8 R% g( c1 J2 I

' h" p3 D& y+ @% Z) xstatic const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {
' F9 ^9 _6 d+ n6 m2 Y        .chipselect     = mx6q_sabresd_spi2_cs,' X. G4 M0 S& r7 ?+ `* n$ n
        .num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),
' I  A/ a$ c! f) K};% l7 i7 C0 _: `+ g5 [
9 z4 \/ M4 C% G/ H. W& P  c; }$ m
static struct spi_board_info mx6_sabresd_spi2_board[]={4 k& G- H8 C* i& F. N6 u) W- E
   [0] = {
  K9 ~7 |& `$ s7 \             .modalias = "enc28j60", . ]1 o: {& a! a  N5 m
             .bus_num = 1,6 R) F! B- k. ~7 L% u$ `$ l
             .chip_select = 0,; T8 h4 e4 D* \
             .max_speed_hz = 5000 * 1000,  B( z/ K9 Y, E
             .mode = SPI_MODE_0,
0 o+ r. F9 ^5 U* R& Z    },
4 v- R# m3 d3 I" ]) {5 k' w5 l4 f
. I' {6 X$ g8 L5 c};' F8 v# `0 b% j- z# h0 |8 W

2 {2 Z9 w/ p$ x+ Z9 t/ I% R. \- w
6 p+ p* T) x% P3 d首先通过宏定义了CS和INT所使用的引脚号,并定义了SPI板级设备。
+ ]( u& P9 |3 g+ c1 R2 \+ X: \
1 t! y  G$ c5 V) i" i接下来我们需要注册该SPI板级设备信息到内核中。
6 F$ J8 [3 `6 y5 O3 |3 s8 n4 ]: e5 V. ]- \# c" T8 A
在同一文件下的mx6_sabresd_board_init函数中添加如下代码:
3 {5 J# p2 E1 y0 p* r& o: R$ u7 L& U7 G5 M6 S4 o% o
/* Following is added by Jone Yim for enc28j60 */1 r7 }8 L; r4 w8 Y* _, d
        imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data); /*using ecspi2*/5 V1 P1 Y0 N5 E3 Z; b; e; v
          q# F5 X1 f% w7 D
        ret = gpio_request(ENC28J60_INTERRUPT_GPIO, "ENC28J60-int");# e8 X% v- L  o6 S
        if (ret) {* U0 ~8 O/ o+ S/ `' H" T$ _
                printk(KERN_ERR"request ENC28J60-int error!!\n");  B. |" n/ T. H$ J1 f( M8 o
        }else{
8 q8 G  _0 h/ N; K: }                gpio_direction_input(ENC28J60_INTERRUPT_GPIO);% k$ s& ?0 q3 e8 B; |' ^) V$ O
                % e2 T: a8 X5 |; T7 k4 \, @& r
                //printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);0 b; q; @* U" G4 t* M/ X' F" B( |
                irq = gpio_to_irq(ENC28J60_INTERRUPT_GPIO);8 Y& k5 Y6 a! ^2 @
                if(irq < 0){# H/ `  A# l) o2 [! v7 l2 x
                        printk(KERN_ERR"claim gpio irq error!!\n");
7 ^: Z( v% P2 n5 s                }else{' B' l. ?5 N5 R
                        printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);7 w; J. x2 O3 w9 m
                        mx6_sabresd_spi2_board[0].irq = irq;+ a6 r& E$ G8 X) W. v4 `: F6 s
                        irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
4 y0 a' Y: @3 |& h; K7 Z                        spi_register_board_info(mx6_sabresd_spi2_board, ARRAY_SIZE(mx6_sabresd_spi2_board));
) V$ W$ E9 @4 ~9 O% W                }
6 h7 p. h9 f' B% W( N/ y3 W3 V        }
0 r, h1 W. @4 `% K/ V* }) J首先注册SPI2控制器,然后在调用spi_register_board_info注册SPI板级设备信息之前,我们向系统申请了用于中断的GPIO引脚,并获取了其irq号,并将该irq号保存到SPI板级设备信息。" b1 i+ F+ O6 O* U7 y# _3 ?. }. @
其次,我们需要设置GPIO的中断类型为下降沿中断,这跟datasheet里面描述的一致。这里提一句为什么要在这里设置中断类型,这是因为在ENC28J60驱动源码的probe方法中并未设置其中断类型,反而是有一段注释要求在bsp中设置中断类型。
7 f- G9 I  l( u, n
; I, B2 C+ N7 T# s3 V: m3 [9 f一切就绪,最后spi_register_board_info调用注册SPI板级设备信息。
# r/ w. R$ h; B0 ^5 I$ V9 {, c; k" S/ c" Z; R/ u
3 l! n" ~3 R- O3 @4 z# z

+ h0 m8 c/ F- v# A- E4.配置内核6 U* A. T: `1 n; C
) Q7 a. W, W8 x, w1 F5 s- D' n
. w* l- C' A0 W- j+ v7 }5 R
配置完以后即可编译。7 v/ M' Z$ [$ j/ g1 l" L

" a% ^& `. G' t5 m" `: Z
' a8 b* h4 v. X4 n
5 Z, E) V4 b) ?! F* ?+ S5.验证
0 \- g% w* D5 S# q2 N2 l# D系统启动后执行如下命令:2 C5 a/ g: o6 i& @! j( B
' p- q3 S% K0 b' K4 B6 i
ifconfig eth0 down   //关闭原有的网口: {; t4 [: |, P' S0 f

1 n) }, ~  M' p" H6 R- w5 H1 gifconfig eth1 up 192.168.0.116   //打开ENC28J60对应的网口并设置IP地址4 j6 J, N0 `! h( Y/ g! z& a! N
; H: I( T+ Y5 |; ?; g/ V; c+ R
4 H3 `5 [! P9 D

+ V8 N% A2 ~1 W/ I# w) ?; Q然后ping以下虚拟机试试:" `& Y& d" w$ _# v! k  N( i

& f  O5 B/ `5 O: m2 h& W: ]: ~0 R- d% ~4 w( K( @" m6 ^
0 F' ^# d. n1 |0 c" R' e! K
ping通了,至此大功告成。  J+ V/ |7 c+ M% T$ B8 b
8 p: s/ D; W/ a: T
8 C4 O. B6 k# |. {3 T' a1 y
9 m' H* W" K7 D. |
0 o/ b+ g7 \0 ~. ~' [$ f9 a' ?) ^

% u6 D( D! B5 F6 K6 G" O/ t7 ?4 a' P4 k5 G+ T* Y

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-30 19:41 , Processed in 0.093750 second(s), 26 queries , Gzip On.

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

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

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