|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
开发板:E9(飞思卡尔的imx6q主控)
1 R. f0 M& [" i! D6 j. d
' n2 p# Q( }. s; o, E内核:Linux 3.0.35! x' f4 t/ g& o, J) P
, V+ M" |% X) l+ k! ~PC OS:Ubuntu 11.04
% o" r2 U+ ~+ \: B: L& T. a" l& y4 Z1 O
1 A) z2 I; ]- [8 | w) [ z8 e
7 z# x+ c( Q8 C- C: Y' V3 T本文对ENC28J60模块的驱动移植进行简单梳理。该模块购于淘宝。
- X0 @: L% B! u" U) \; F- u q' M& X9 D% h+ N$ e
按照一般移植要素,有如下几个步骤:
1 k0 T6 d$ u2 ]1 D* d& I T7 H. b9 z- x
1. 按照各引脚所对应的功能进行初始化操作。
7 m7 {8 O* y4 z8 P) h
# X9 m* ^& H4 N! a1 g' r" p2. 确定总线类型,在bsp中注册相应的主控制器信息。
) @; D* ]. z B8 q# o9 M& o
5 K. O$ y( e$ f, T* E C3.在bsp中添加设备信息。8 K% ?7 s5 K# i5 c. a5 E
9 N8 S+ x# @- C, Y
4. 配置内核,打开设备配置选项。* E* h. S y/ J+ Z& n
) }* I; u5 j1 S) z0 F( w% K6 ~4 h0 F0 n2 ?' h. s
% i' ^# [( i% i$ v- r7 `; D4 C& R( Q
1. 硬件连线方式) H- i! J/ v. ~) ?: H d5 ~% m
IMX6开发板 ENC28J60
2 [6 q1 C+ s0 R/ w$ Y7 t4 m1 @3 q1 `, t V- W, t; P4 ^
CSPI2_CLK ---> SCK! P4 ?6 M3 f) ^5 }! I# X( n
4 x& c" n- i$ U0 R4 G7 G: c
CSPI2_MISO <--- SO
6 j8 S5 ]! _. x6 \) d* K1 z* N4 F0 ], q3 ?9 R7 P
CSPI2_MOSI ---> SI0 |$ s5 \. W; f9 y5 q: Q; q
( o7 }% F$ E' f, f' t( ?' Z
CSPI_CS0 ---> CS
. F" X% d( X1 [0 W5 D' w4 ]
( F8 Y. b: Y' U& nEIM_D21 <--- INT
! v9 W t, ]7 c0 s2 O- v7 V7 Q
* m: p) f* i, O2 P0 ?VCC 3.3v ---> VCC1 b5 q! |, v0 w; S$ M
6 w2 c1 @5 t2 R# G- F) z; eGND --> GND
! O2 O6 A0 `) S% @& |6 q, D. ~. V; r3 g: S7 T; h \! S. ?
3 Y" A5 f* Y& a3 c# i+ L
, c: L! G/ D) f" P0 l
4 X; F2 j/ A: e4 ?: v' j4 n4 s2. 初始化引脚 [/ ^ F: h/ v6 {3 O
从硬件连线方式可以看出,SPI总线使用的是imx6的SPI2控制器,同时额外需要一个GPIO作为中断引脚。
Z }: Y1 d* @7 G# j# x6 V. }
0 R* r( F; c ]0 h( O6 @+ Q在原文件arch/ARM/mach-mx6/board-mx6q_sabrESD.h的数组mx6q_sabresd_pads数组中添加如下内容: R5 p/ F% ]# a
9 I/ v7 o2 e2 M" J2 _! I
/* ECSPI2*/
7 r& ^0 C) s7 v: `3 Z+ y MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,! J- _: V- ~3 `* A7 R+ x+ @! H
MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,) u" p; F; D0 T/ l
MX6Q_PAD_EIM_OE__ECSPI2_MISO,
& X) ?( J8 O9 @0 u# q8 D MX6Q_PAD_CSI0_DAT11__GPIO_5_29, - A: d% ]+ x& X/ [/ |6 `$ d
//MX6Q_PAD_EIM_D17__GPIO_3_17,& Y6 F- O! d, z3 \
( I1 K, T6 X! a# N1 R, ] MX6Q_PAD_EIM_D21__GPIO_3_21, /* gpio interrupt for enc2860j */
: N' F6 A% v6 ], U" [5 ^
# g" L, X2 ]5 D# N7 z8 K- }% Y3. 注册SPI控制器和SPI板级设备) t5 S) X! L% m2 q2 t. `# l
由于ENC28J60使用SPI总线,因此,在注册板级设备设备前,需要弄SPI的一些参数。" e8 }/ N$ z" n0 ^; e+ ?' A% P5 |/ k4 G
+ y$ s7 p8 ^! s- n% j5 z
ENC28J60使用SPI模式0进行传输,最大速率为10Mbps。
0 ~. L% l! M% ]' h9 v1 @1 f# L" C. m3 ?' _, P8 A9 Y
在原文件arch/arm/mach-mx6/board-mx6q_sabresd.c中添加如下结构体的声明:; d- o6 Q9 }1 ^7 I( [( e M
, F; C2 m G2 o5 I1 `, ~7 N; J+ g/* Following is added by Jone Yim for enc28j60 */# @1 w8 m* H; ^8 i9 F
#define SABRESD_ECSPI2_CS0 IMX_GPIO_NR(5, 29) /* CSPI2_CS0 */
' D: \9 b( h: c5 w4 k0 ~; `#define ENC28J60_INTERRUPT_GPIO IMX_GPIO_NR(3, 21) /* EIM_D21 */, U2 B9 B2 o4 U
' [6 A) ], v7 {3 G1 E3 p4 I
static int mx6q_sabresd_spi2_cs[] = {
0 D% d' [1 K1 ^1 p SABRESD_ECSPI2_CS0,* j; z; I) Z! e( ^" U
};
$ o) F8 K: ?0 Y: [7 U* O: F) N5 ?0 B9 m+ j2 w
static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {3 b' [) |& T+ C5 s+ W0 y
.chipselect = mx6q_sabresd_spi2_cs,# X+ _4 Y9 ?. F7 V" r
.num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi2_cs),) j0 L. Y- U# u/ l2 p o1 f
};
+ j+ s0 w) D0 h' m6 m& ?( v: h1 l) M& L9 z: O' S7 f7 K6 C% R
static struct spi_board_info mx6_sabresd_spi2_board[]={$ t0 H, D: l- X# u! {
[0] = {
" {: D* V+ W. l7 [3 i' c/ M .modalias = "enc28j60",
4 [- u( k! p8 L" |4 P .bus_num = 1,
) ?' H' B/ S' u- E' h: C .chip_select = 0,
4 _; h- t) I8 P* M" R# y .max_speed_hz = 5000 * 1000,/ d+ Q0 ]# \3 n" S
.mode = SPI_MODE_0,. e' A6 i1 T" [, ]% @1 ]# g# `9 v
},, s' }7 v: j9 L5 T( s6 N
4 B2 y* k1 ^1 Y$ l5 l! ]3 M};
* Z* z# L9 I+ [% N" _* m. R6 O/ R% D X' O! k, `. F
$ a- {, |7 c5 e6 `( n
首先通过宏定义了CS和INT所使用的引脚号,并定义了SPI板级设备。
p! r; ?3 o) c1 t1 C9 ]1 M
9 t, [, L3 ^' l2 t7 F- c6 Z) q接下来我们需要注册该SPI板级设备信息到内核中。8 C) l* f3 {4 B9 p
0 P+ [5 C" B0 n8 O+ E0 w+ _2 F
在同一文件下的mx6_sabresd_board_init函数中添加如下代码:
3 @7 M7 L) ?* x# R1 n3 C0 d
9 n, T! `, y5 `( T; D0 p5 O/* Following is added by Jone Yim for enc28j60 */
" {8 i4 H& J8 n" R2 j8 m& _ imx6q_add_ecspi(1, &mx6q_sabresd_spi2_data); /*using ecspi2*/ E/ J% V7 _5 s" ]9 l: w) k# Z
) N6 A( x/ M, M; S, ^
ret = gpio_request(ENC28J60_INTERRUPT_GPIO, "ENC28J60-int");
2 M' q* q& {/ U* C$ q- _& F if (ret) {
# Y" u; }8 d; q% o printk(KERN_ERR"request ENC28J60-int error!!\n");
1 ~# y* V! J4 j8 G. k; I3 J" | }else{4 R8 X1 \, z- u J* H+ P
gpio_direction_input(ENC28J60_INTERRUPT_GPIO);8 X) H8 e+ h# o6 m6 K
( s- e/ @, q+ y$ {" [ //printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);* D; V5 w2 M2 y- x5 n
irq = gpio_to_irq(ENC28J60_INTERRUPT_GPIO);
2 T: y# r8 @/ w2 e# Q& S if(irq < 0){
6 R S9 O8 j3 h: a) U printk(KERN_ERR"claim gpio irq error!!\n");
+ N4 H4 R# E, s }else{8 g0 s& H4 w/ p1 x
printk("enc28j60 gpio %d irq %d\n", ENC28J60_INTERRUPT_GPIO, irq);
6 v* d8 r0 {( [2 J mx6_sabresd_spi2_board[0].irq = irq;
* q; _4 D" X( n irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);9 A# N; m/ a; \& m& R& W
spi_register_board_info(mx6_sabresd_spi2_board, ARRAY_SIZE(mx6_sabresd_spi2_board));
6 N' C+ i, l: x7 Y5 h1 G }
7 W0 |( p( _( E" _2 k1 | }
9 j6 C4 o0 ?: g5 G% E% H- F首先注册SPI2控制器,然后在调用spi_register_board_info注册SPI板级设备信息之前,我们向系统申请了用于中断的GPIO引脚,并获取了其irq号,并将该irq号保存到SPI板级设备信息。
- P" o: C* G) M: `其次,我们需要设置GPIO的中断类型为下降沿中断,这跟datasheet里面描述的一致。这里提一句为什么要在这里设置中断类型,这是因为在ENC28J60驱动源码的probe方法中并未设置其中断类型,反而是有一段注释要求在bsp中设置中断类型。
+ @3 C# _3 @! P6 } Z d$ q
, R, E l- m; P9 Z, B1 \一切就绪,最后spi_register_board_info调用注册SPI板级设备信息。
" ~3 b4 |7 F$ R7 \9 m3 `- h8 R7 q% k' ]
5 S5 h# {% |) u( n" X" E* l! Q$ t
3 N' R3 P1 W [1 G ?3 e/ Y
4.配置内核
( B" D" V$ O, x& N2 B) Z
3 [; `, c- s6 e
7 b5 d0 ?+ X+ J+ o配置完以后即可编译。
. X" ]- C ]+ o) P. Z# X, {2 S
: C. D( Y3 q1 E+ c. i) F* o G, P8 S0 F7 @
# s0 ~2 U- W* A+ f! X Z- u# d2 a" A5.验证
3 M1 L" u1 X5 Y2 o% h- w7 x5 x系统启动后执行如下命令:
7 I: G- x) `1 _# l
% C% x8 W% e8 w) R5 }8 Z7 Fifconfig eth0 down //关闭原有的网口
, x( ~6 K9 U7 e% ?& w
. H1 U _3 ]$ _. F7 K8 hifconfig eth1 up 192.168.0.116 //打开ENC28J60对应的网口并设置IP地址
6 J* |5 m: Q8 [# ]' g/ t# D/ D/ L. H! j9 b
K# p$ K3 y$ C6 l3 s7 [* O6 R7 w$ G9 H7 X
然后ping以下虚拟机试试:) _& b% `' U+ J, i. H
+ E0 l' j+ v0 n7 ~' c, l3 X1 E& _4 }
& }2 F! D' t5 a2 m( }5 N3 g* ^ping通了,至此大功告成。7 o/ a7 A& A6 x* S
5 n2 Q! ]2 k0 U6 z: j
% y* }& Y: _8 k" C" ~7 d$ K0 u
6 _ B4 |0 s* ~0 a; r9 Q; m
4 _, ?* E4 i1 l6 N
7 A! N: l/ N3 x7 ? ]% k! I# _9 ~7 }' `, k* K% _+ t, ~3 f* \
|
|