EDA365电子论坛网
标题:
Linux驱动移植——ENC28J60以太网控制器
[打印本页]
作者:
piday123
时间:
2020-5-27 16:17
标题:
Linux驱动移植——ENC28J60以太网控制器
开发板:E9(飞思卡尔的imx6q主控)
+ x6 r5 ] F# G. F9 F: Z5 n
9 K) r; q/ @. V# Q9 a$ k
内核:Linux 3.0.35
0 F% X9 P$ t% s+ D
3 x, {: \; } j; j3 J7 _' s' I
PC OS:Ubuntu 11.04
( w# }' s* Q8 R3 H# l
6 b; {5 h1 q% K8 ~8 f. T
' U: r! |3 D# I- K2 S
) w1 E% @/ |4 B+ z
本文对ENC28J60模块的驱动移植进行简单梳理。该模块购于淘宝。
9 h- O. y# ~ o
, O8 X$ z7 x- y
按照一般移植要素,有如下几个步骤:
! q2 s9 h6 f, l K: d3 x
! `8 h9 ?" @) S* G4 E2 D
1. 按照各引脚所对应的功能进行初始化操作。
+ a; n3 p8 A$ f& \& v& o
! K- z2 C1 P3 ?4 S7 S( f7 s
2. 确定总线类型,在bsp中注册相应的主控制器信息。
k& x: C o6 H" P8 R: ^. }6 V
4 l" Z3 o" N# S; }
3.在bsp中添加设备信息。
5 @: p9 D* P! ?6 {# k( i5 u
3 c. U% ]- N+ P* A
4. 配置内核,打开设备配置选项。
; b ` ~* e, G2 p& G
$ A$ e5 V- ~& H# @
. k% ~) B$ r" I4 c% r
* l# A8 t' H: }/ g
1. 硬件连线方式
. w: o7 V7 _1 W% T+ K; K- V4 o
IMX6开发板 ENC28J60
( w# o6 ~) @4 I0 @' ^+ V
' Q8 O) ?: M3 A Z
CSPI2_CLK ---> SCK
% O" p- y/ [; E# b$ F2 ^7 w
) ~8 o+ Y& f( D. q
CSPI2_MISO <--- SO
H# c$ J8 P6 c, n4 L
/ d; A- I$ t* \# R5 w2 k3 M
CSPI2_MOSI ---> SI
2 l( N* y+ T5 i+ q, Q4 P& i0 n
. m7 c" B) \* u) P3 y- `+ ~- L7 n o
CSPI_CS0 ---> CS
+ m/ b( W9 V1 \4 f; x! l' a9 m
( [8 m# U4 _; ]) ]1 y5 m8 k6 o' b
EIM_D21 <--- INT
. T+ Q8 ]* @" W7 _% x1 c+ q( h
# f K5 Y3 d5 _+ \5 t/ H `
VCC 3.3v ---> VCC
4 J1 D/ a" T8 |+ ]1 }' i( h
# O0 d0 C [ l6 v) D
GND --> GND
9 v& O6 B; ~: R7 ~. y5 h' ?, H
$ A: b9 D* ~7 L3 W+ y: {- t* ~
2 _8 h% k/ Y0 z; h5 d! v5 Y
. w% V. Q2 ~; o; @0 m2 D
0 w: e5 M l7 f( e2 ~
2. 初始化引脚
6 L3 }! \+ j+ ?% K9 t
从硬件连线方式可以看出,SPI总线使用的是imx6的SPI2控制器,同时额外需要一个GPIO作为中断引脚。
( @; C4 E# h4 u0 l& d3 |
, J" G9 m' h6 _# k
在原文件arch/arm/mach-mx6/board-mx6q_sabresd.h的数组mx6q_sabresd_pads数组中添加如下内容:
& j% Y3 j9 ^; Q7 W1 ~! p; `
. A, v- z- ~9 T
/* ECSPI2*/
* } y# {- V8 f5 u# y0 T1 h- p: W
MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
3 O) B/ i$ e2 d! d9 P& G- Y1 h( K
MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,
, x# G" F( L/ o
MX6Q_PAD_EIM_OE__ECSPI2_MISO,
: M6 d+ M" p/ M
MX6Q_PAD_CSI0_DAT11__GPIO_5_29,
' ~' G$ o+ y$ G+ ^4 y( W
//MX6Q_PAD_EIM_D17__GPIO_3_17,
1 G) n- ?, h, B _6 Y, j4 P# y
& R2 x! f, }# o, o* ^' G
MX6Q_PAD_EIM_D21__GPIO_3_21, /* gpio interrupt for enc2860j */
6 }3 a/ O* j# i$ Y- c
5 Q0 G: f, J) @ y
3. 注册SPI控制器和SPI板级设备
& t8 T0 y9 p ?8 o" {& ^) \
由于ENC28J60使用SPI总线,因此,在注册板级设备设备前,需要弄SPI的一些参数。
: J; q) Z' M# L$ f. ^& }2 ?- F
, z" q- ]! R3 C6 ~4 t
ENC28J60使用SPI模式0进行传输,最大速率为10Mbps。
* d6 |- H. U8 p6 T6 A
9 m3 d0 w( I. O0 z6 W8 r
在原文件arch/arm/mach-mx6/board-mx6q_sabresd.c中添加如下结构体的声明:
9 D) }; ~! p' i a* x! w
: q/ k- G- g6 z% X0 c7 ^% B
/* Following is added by Jone Yim for enc28j60 */
# f7 e( ^- [/ ^! P8 g! d
#define SABRESD_ECSPI2_CS0 IMX_GPIO_NR(5, 29) /* CSPI2_CS0 */
+ \% \! n& \$ c. g. H0 L. S4 N
#define ENC28J60_INTERRUPT_GPIO IMX_GPIO_NR(3, 21) /* EIM_D21 */
7 c/ F7 M8 |2 @5 a4 d
% G+ {& @0 R2 w( }" [% [9 a$ H- }
static int mx6q_sabresd_spi2_cs[] = {
& i" h: _( T( D n' O) l
SABRESD_ECSPI2_CS0,
/ f$ [% @/ U3 H6 I
};
5 }6 v. d4 G7 B2 h8 z
" U+ P- Z2 W; u7 `( p
static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {
0 m/ c- Q0 \( ~
.chipselect = mx6q_sabresd_spi2_cs,
, E. n5 e, Y- |1 q$ _
.num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),
9 A: F Z5 Z$ u. B( f8 ?2 }/ X) ^
};
5 ?5 N" R) F+ J
6 M5 |: U0 ?2 g7 B1 S7 B9 Y5 \
static struct spi_board_info mx6_sabresd_spi2_board[]={
; f2 C% j. e: i7 x P
[0] = {
. d/ k' E2 w' s' K: ~& b# ^, k
.modalias = "enc28j60",
& @( ^" {) j" Y
.bus_num = 1,
; Z* ~$ D1 Q) e1 F/ s- h7 P
.chip_select = 0,
R+ I$ Y4 a3 W7 K
.max_speed_hz = 5000 * 1000,
% I4 c/ R/ J: z" }# n" c4 t$ |" m
.mode = SPI_MODE_0,
& @8 S" f' T& H# h2 W
},
9 H }! Q/ d5 j. K
1 z- B, L8 H7 y
};
& X5 ~7 H4 J8 I, j" z
2 O; u6 x7 [& E; [
! E) P4 z- E$ {; V
首先通过宏定义了CS和INT所使用的引脚号,并定义了SPI板级设备。
7 D; Q5 ]( r6 n; ^* {$ x% x
8 @# |* j. b) M; j
接下来我们需要注册该SPI板级设备信息到内核中。
* _3 ~% m8 L: Z/ y$ l
* c+ ` T: a$ A8 m* e
在同一文件下的mx6_sabresd_board_init函数中添加如下代码:
5 |/ P! z: ?8 r" b9 M
% M2 B$ r6 ~; T2 w- a
/* Following is added by Jone Yim for enc28j60 */
- n* C l2 h1 k; T) F
imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data); /*using ecspi2*/
5 V8 f6 ?- _) C5 K* A) ]
# g+ [5 [" S$ W& ]7 B+ ?
ret = gpio_request(ENC28J60_INTERRUPT_GPIO, "ENC28J60-int");
X8 I( v+ t7 Y4 h9 J
if (ret) {
* Q0 s2 m) B$ s& t
printk(KERN_ERR"request ENC28J60-int error!!\n");
/ N9 n! K9 b7 m0 V4 ^% Q
}else{
# J" c- H5 O. ~8 o% y+ R9 a9 S4 W
gpio_direction_input(ENC28J60_INTERRUPT_GPIO);
& t( z; E1 O" \; x; B
: \. i. y& B. u G, h5 Q
//printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);
- C+ u+ U$ K+ }
irq = gpio_to_irq(ENC28J60_INTERRUPT_GPIO);
) f1 \/ Y" O6 G( H) g8 H
if(irq < 0){
4 ~0 r3 X- u5 x0 j/ u$ x1 g. G( r
printk(KERN_ERR"claim gpio irq error!!\n");
! E0 b/ m" T+ {! y
}else{
2 I( I" q k$ B& T) A5 d% Z
printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);
, O: x2 Q5 I7 o0 K, ?* w
mx6_sabresd_spi2_board[0].irq = irq;
2 K* A) m$ S! x. [ ?) m
irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
( @6 a. m0 [9 U
spi_register_board_info(mx6_sabresd_spi2_board, ARRAY_SIZE(mx6_sabresd_spi2_board));
% \8 H ?6 t6 m
}
1 G9 S$ ~; p- ]* B! ~! j/ q" h4 S
}
6 j0 i) v7 H3 ?1 v5 Y$ O o, Q
首先注册SPI2控制器,然后在调用spi_register_board_info注册SPI板级设备信息之前,我们向系统申请了用于中断的GPIO引脚,并获取了其irq号,并将该irq号保存到SPI板级设备信息。
/ z) V/ T- J. s" w: E0 E7 h
其次,我们需要设置GPIO的中断类型为下降沿中断,这跟datasheet里面描述的一致。这里提一句为什么要在这里设置中断类型,这是因为在ENC28J60驱动源码的probe方法中并未设置其中断类型,反而是有一段注释要求在bsp中设置中断类型。
3 o7 {& R1 G, N+ k5 w7 R3 j/ p
- h9 F- T% q6 K
一切就绪,最后spi_register_board_info调用注册SPI板级设备信息。
3 f) X6 O; p. R" s- B. O
+ ? w4 C! A* G' j- p! e
6 t1 B# m6 b5 i8 e
0 {8 K( ^0 o4 D
4.配置内核
$ g# \5 M, `) H; j1 x% N2 D1 S
11.jpg
(67.85 KB, 下载次数: 2)
下载附件
保存到相册
2020-5-27 16:16 上传
( B* x9 d* c: h$ C- [1 I) W
0 G' S7 B; ?4 |7 ^
配置完以后即可编译。
/ g4 k/ A/ H9 a9 |# d
' [2 o! P. S5 Y5 G( D4 s# m
( `4 u( [/ U0 D! o$ ], [( G* p
$ O4 ?* ~- @3 Y* `; H2 ]" ~
5.验证
# B4 X7 q, z7 x! Y/ b+ Z' ~8 L8 u
系统启动后执行如下命令:
9 g) J: E6 p7 f4 F; s
/ ^, I" u# P) ?* ^, l" d* d6 Y
ifconfig eth0 down //关闭原有的网口
: _7 U8 a. B9 k* Q3 G6 Y/ \, D
7 I: E. n9 o' N$ w" H
ifconfig eth1 up 192.168.0.116 //打开ENC28J60对应的网口并设置IP地址
0 O% x% h* z" ?
/ { m8 M$ Z$ ^, I t Q% O8 y
; w. H c, i1 D5 _1 q
/ ]8 c' y- U0 A% N; P/ F9 X) F
然后ping以下虚拟机试试:
" p! V" p0 c/ _+ u; y* C h& s
10.png
(20.7 KB, 下载次数: 4)
下载附件
保存到相册
2020-5-27 16:16 上传
2 Z: K: H2 A8 h) c. T d
: _; C: V1 ]3 s$ ^8 q+ R
2 k" b8 m) o7 J, m- B: l' N4 i7 M
ping通了,至此大功告成。
+ C9 g N- @8 h X- u
2 F1 N7 Q3 u" {# ?% A
7 W( x7 `3 Q' S
& n. m4 }$ i, R* Z, {
& d/ r/ _, |& m3 z* V/ F! R
) `# ]6 d: g( K# x8 t; e
' `) o r9 s$ t4 g
作者:
NingW
时间:
2020-5-27 17:05
ENC28J60以太网控制器
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2