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