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