|
|
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
|
|