第1章 ZLG/CF躯动使用 1.1基于LPc2210的 ZLG/CF驱动使用 CF卡有PC卡1O、 MEMORY及 True Ide等3种模式,而 True IDE模式兼容IDE硬 盘,该模式比其它的两种模式更实用,是3种模式中使用较多的一种。本节中描述CF卡在 True ide模式下的应用。 使用LPC2210的通用可编程IO口,模拟产生ATA设备的读写时序,实现对CF卡及 IDE硬盘等ATA设备读写操作。使用LPC220的GPIO功能,可以非常灵活而简单地实现 ATA读写时序 111LPC2210与CF卡及IDE硬件连接 LPC2210的GPIO引脚与CF卡及IDE硬盘的硬件接线图分别如图1.1、图1.2所示 P2.19D19 26 P227D27 P020 642 POZ MAT HEADER ATA D 图1.1LPc2210与F卡接线图 注意:图1.1中CF卡的CSEL引脚直接接地,开发板上的CF卡已被配置为主设备。IDE硬盘的主从 配置,通过硬盘上的跳线选择
第1章 ZLG/CF 驱动使用 1.1 基于 LPC2210 的 ZLG/CF 驱动使用 CF 卡有 PC 卡 I/O、MEMORY 及 True IDE 等 3 种模式,而 True IDE 模式兼容 IDE 硬 盘,该模式比其它的两种模式更实用,是 3 种模式中使用较多的一种。本节中描述 CF 卡在 True IDE 模式下的应用。 使用 LPC2210 的通用可编程 I/O 口,模拟产生 ATA 设备的读写时序,实现对 CF 卡及 IDE 硬盘等 ATA 设备读写操作。使用 LPC2210 的 GPIO 功能,可以非常灵活而简单地实现 ATA 读写时序。 1.1.1 LPC2210 与 CF 卡及 IDE 硬件连接 LPC2210 的 GPIO 引脚与 CF 卡及 IDE 硬盘的硬件接线图分别如图 1.1、图 1.2 所示。 ATA_DASP 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 J17 HEADER 25X2_CF ATA_DASP D4 LED VCC P2.24_D24 P2.25_D25 P2.26_D26 P2.27_D27 P2.28_D28 P2.29_D29 P2.30_D30 P2.31_D31 P1.20 P0.21_PWM5 P0.19_MAT1.2 P0.20_MAT1.3 VDD3.3 VDD3.3 P0.17_CAP1.2 P0.22_MAT0.0 VDD3.3 P1.25 P1.24 P2.18_D18 P2.17_D17 P2.16_D16 P1.16 P1.17 P1.18 VDD3.3 P1.19 P2.23_D23 P2.22_D22 P2.21_D21 P2.20_D20 P2.19_D19 R94 1K 图 1.1 LPC2210 与 CF 卡接线图 注意:图 1.1 中 CF 卡的 CSEL 引脚直接接地,开发板上的 CF 卡已被配置为主设备。IDE 硬盘的主从 配置,通过硬盘上的跳线选择
MAT13929 VCC 图1.2LPc2210与IDE硬盘接线图 表1.1为LPC2210的GPO引脚与CF卡及IDE硬盘引脚连接分配表,表中描述了各 GPIO引脚与CF卡及IDE硬盘对应的控制信号线,根据表中的描述配置LPC2210相关的寄 存器。 表1.1LPc2210的GP|O引脚与CF卡及DE硬盘连接引脚分配 LPc2210cF卡1DE硬盘 LPC2210CF卡DE硬盘1o P0.17 RESET-RESET O‖*PL.17 P216-P231D00D15|DD-DD15I、O‖*P1.16 A00 DAO P1.19 0000 P0.19 OP1.23 CSEI DIOR O‖P124 IOCS16-1OCS16 IORDYIORDY I‖P1.25 pdiag-PDlAG P1.21 P1.18 DA2 NTR 注:1.I/0输入与输出是相对于LPC2210来说的,I为LPC2210的输入,0为输出。 2.表中“*”号的引脚,为使用到的引脚,其它引脚不需使用,但需要配置为适当的状态 根据图1.1、图12和表1.1所描述,为相关的引脚定义有意义的标号,如程序清单1.1 程序清单1.1ATA接口连接引脚定义 /* Eeay ARM2200和IDE接口连接 Fifdef ATA BUS AT 8bit /*8位总线* Define ATA DATA0x00ff0000/* eeayAR2200和IDE接口直接相连,p2.16p2.23*/ /*16位总线* #define ATA DATA 0xfff0000/* Ebay ARM220和IDE接口直接相连,p2.16p2.31*/ fendi
GND P2.23_D23 P2.24_D24 P2.22_D22 P2.25_D25 P2.21_D21 P2.26_D26 P2.20_D20 P2.27_D27 P2.19_D19 P2.28_D28 P2.18_D18 P2.29_D29 P2.17_D17 P2.30_D30 P2.16_D16 P2.31_D31 GND GND GND P0.17_CAP1.2 P0.21_PWM5 P0.22_MAT0.0 P0.18_CAP1.3 P0.19_MAT1.2 P0.20_MAT1.3 GND GND GND 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 J3 IDE/USER_COM NC R32 10K P1.16 P1.17 P1.18 P1.19 P1.20 P1.21 P1.24 P1.25 VDD3.3 R31 10K R33 10K R13 10K VDD3.3 ATA_DASP D4 LED VCC ATA_DASP R94 1K P1.23 图 1.2 LPC2210 与 IDE 硬盘接线图 表 1.1 为 LPC2210 的 GPIO 引脚与 CF 卡及 IDE 硬盘引脚连接分配表,表中描述了各 GPIO 引脚与 CF 卡及 IDE 硬盘对应的控制信号线,根据表中的描述配置 LPC2210 相关的寄 存器。 表 1.1 LPC2210 的 GPIO 引脚与 CF 卡及 IDE 硬盘连接引脚分配 LPC2210 CF 卡 IDE 硬盘 I/O LPC2210 CF 卡 IDE 硬盘 I/O *P0.17 -RESET -RESET O *P1.17 A01 DA1 O *P2.16~P2.31 D00~D15 DD0~DD15 I 、O *P1.16 A00 DA0 O P0.18 DMARQ I *P1.19 -CS0 -CS0 O *P0.19 -IOWR -DIOW O P1.23 CSEL O *P0.21 -IORD -DIOR O P1.24 -IOCS16 -IOCS16 I P0.22 IORDY IORDY I P1.25 -PDIAG -PDIAG I P1.21 -DMACK I *P1.18 A02 DA2 O P0.20 INTRQ INTRQ I *P1.20 -CS1 -CS1 O 注:1.I/O 输入与输出是相对于 LPC2210 来说的,I 为 LPC2210 的输入,O 为输出。 2.表中“*”号的引脚,为使用到的引脚,其它引脚不需使用,但需要配置为适当的状态。 根据图 1.1、图 1.2 和表 1.1 所描述,为相关的引脚定义有意义的标号,如程序清单 1.1 所示。 程序清单 1.1 ATA 接口连接引脚定义 /* EeayARM2200 和 IDE 接口连接 */ #ifdef ATA_BUS_AT_8bit /*8 位总线*/ #define ATA_DATA 0x00ff0000 /* EeayARM2200 和 IDE 接口直接相连,p2.16~p2.23 */ #else /*16 位总线*/ #define ATA_DATA 0xffff0000 /* EeayARM2200 和 IDE 接口直接相连,p2.16~p2.31 */ #endif
E AO (1<16)/ eeayAR2200和IDE接口直接相连,p1.16*/ #define IDE AI (1<17)/ BayaR2200和IDE接口直接相连,p1.17*/ (1<<18) /* EeayAR2200和IDE接口直接相连,p1.18* # define IDE CS0(1<19)/ EeayARM2200和IDE接口直接相连,p1.19* define IDE CSI /* eeayARM2200和IDE接口直接相连,p1.20* IDE DMACK (1<<21) /* EeayARM2200和IDE接口直接相连,p1.21*/ Define IDE CSEL (1<<2 /* EeayARM2200和IDE接口直接相连,p1.23* IDEI0CS16(1<24)/ eeayARy2200和IDE接口直接相连,p1l.24*/ IDE PDIAG(1<25)/ eeayARy2200和IDE接口直接相连,p1.25*/ #define IDE RST (1<<17) /* eeayarM2200和IDE接口直接相连,p0.17*/ DE_ DMAREQ(14<18)/ EeayARy2200和IDE接口直接相连,p0.18*/ #define (1<19)/ Eeayarla00和IDE接口直接相连,p0.19* define IDE INTRQ(1<20)/ EeayARM2200和IDE接口直接相连,p0.20*/ Define (1<21)/* Ebay ARM2200和IDE接口直接相连,p0.21*/ Eeay ARM2200/ #define Addr CS at P1 (IDE A0+ IDE Al +IDE A2+ IDE CS0 IDE CS1) #define MASK DATA CATA DATA) 1.1.2函数接口的实现 1.ATA设备寄存器读写函数 IDEA0、IDEA1、IDEA2地址信号引脚和 IDE CS0、 IDE CS1片选信号引脚都是在 LPC2210的P1口上,正好由这些信号线确定ATA设备一个具体寄存器的地址;为了便于地 址的设定,将P1口上同时为高电平的信号引脚定义为 Addr cs at p宏,如程序清单1.1(1) 所示 为了便于数据总线的方向改变和数值输出,可定义数据输出的屏蔽值 MASK DATA如 程序清单1.1(2)所示 模拟读ATA设备寄存器步骤如下 (1)关系统中断,预防在读寄存器操作中产生中断 (2)准备读取设备数据信号,设置GPIO模拟ATA接口数据的引脚为输入状态 (3)设置寄存器的相应地址; (4)使读ATA设备寄存器的信号引脚为低电平 (5)读取GPO模拟ATA接口数据的引脚的电平(这时数据线上的值应为设备寄存器中 的值),并调整数据位置 (6)使读ATA设备寄存器的信号引脚为高电平; (7)如果ATA设备(CF卡)是8位总线模式,并且操作的是数据寄存器(16位),则 需重复(3)、(4)、(5)步,再整合成16位的数据。 (8)取消ATA设备寄存器地址的选择 (9)开系统中断。 GPIO模拟读ATA设备寄存器的函数如程序清单12所示,ATA设备各寄存器地址宏定
#define IDE_A0 (1<<16) /* EeayARM2200 和 IDE 接口直接相连,p1.16 */ #define IDE_A1 (1<<17) /* EeayARM2200 和 IDE 接口直接相连,p1.17 */ #define IDE_A2 (1<<18) /* EeayARM2200 和 IDE 接口直接相连,p1.18 */ #define IDE_CS0 (1<<19) /* EeayARM2200 和 IDE 接口直接相连,p1.19 */ #define IDE_CS1 (1<<20) /* EeayARM2200 和 IDE 接口直接相连,p1.20 */ #define IDE_DMACK (1<<21) /* EeayARM2200 和 IDE 接口直接相连,p1.21 */ #define IDE_CSEL (1<<23) /* EeayARM2200 和 IDE 接口直接相连,p1.23 */ #define IDE_IOCS16 (1<<24) /* EeayARM2200 和 IDE 接口直接相连,p1.24 */ #define IDE_PDIAG (1<<25) /* EeayARM2200 和 IDE 接口直接相连,p1.25 */ #define IDE_RST (1<<17) /* EeayARM2200 和 IDE 接口直接相连,p0.17 */ #define IDE_DMAREQ (1<<18) /* EeayARM2200 和 IDE 接口直接相连,p0.18 */ #define IDE_WR (1<<19) /* EeayARM2200 和 IDE 接口直接相连,p0.19 */ #define IDE_INTRQ (1<<20) /* EeayARM2200 和 IDE 接口直接相连,p0.20 */ #define IDE_RD (1<<21) /* EeayARM2200 和 IDE 接口直接相连,p0.21 */ /* EeayARM2200 */ #define Addr_CS_at_P1 (IDE_A0 + IDE_A1 +IDE_A2 + IDE_CS0 + IDE_CS1) (1) #define MASK_DATA (~ATA_DATA) (2) 1.1.2 函数接口的实现 1.ATA 设备寄存器读写函数 IDE_A0、IDE_A1、IDE_A2 地址信号引脚和 IDE_CS0、IDE_CS1 片选信号引脚都是在 LPC2210 的 P1 口上,正好由这些信号线确定 ATA 设备一个具体寄存器的地址;为了便于地 址的设定,将 P1 口上同时为高电平的信号引脚定义为 Addr_CS_at_P1 宏,如程序清单 1.1(1) 所示。 为了便于数据总线的方向改变和数值输出,可定义数据输出的屏蔽值 MASK_DATA.如 程序清单 1.1(2)所示。 模拟读 ATA 设备寄存器步骤如下: (1) 关系统中断,预防在读寄存器操作中产生中断; (2) 准备读取设备数据信号,设置 GPIO 模拟 ATA 接口数据的引脚为输入状态; (3) 设置寄存器的相应地址; (4) 使读 ATA 设备寄存器的信号引脚为低电平; (5) 读取 GPIO 模拟 ATA 接口数据的引脚的电平(这时数据线上的值应为设备寄存器中 的值),并调整数据位置; (6) 使读 ATA 设备寄存器的信号引脚为高电平; (7) 如果 ATA 设备(CF 卡)是 8 位总线模式,并且操作的是数据寄存器(16 位),则 需重复(3)、(4)、(5)步,再整合成 16 位的数据。 (8) 取消 ATA 设备寄存器地址的选择。 (9) 开系统中断。 GPIO 模拟读 ATA 设备寄存器的函数如程序清单 1.2 所示,ATA 设备各寄存器地址宏定
义如程序清单1.5所示。 程序清单12读取ATA设备寄存器函数 #ifdef ATA BUS at &bit uint16 SYs PortIn(uint32 reg) /*8位总线的读寄存器函数* uint16 res OS ENTER CRITICALO /*关中断考 IO2DIR= IO2DiR MASK DATA. *定义输出口其它为输入( ATA DATA为输入)* IOICLR= CS at P1 地址与片选信号都为低电平 IOISET=re 地址高电平位输出,完成地址的设置 读低字节 IOOCLR= IDE RD /读信号脚置低 res=(uint8 ((O2PIN&ATA DATA)>>16) 读取数据* IOOSET= IDE RD 使读信号为高* 读高字节 f(reg=ATA REG DATA 如果读数据寄存器,读高字节制 IOOCLR= IDE RD /*读信号脚置低 +=m0 IN&ATA DAtar>8x读取数据 IOOSET= IDE RD /*使读信号为高 IO1SET= Addr cs at PI 输出控制信号置高 OS EXIT CRITICALO: /*开中断 return res 返回数值 uint16 sYs Portin(uint32 reg) /*8位总线的读寄存器函数* OS ENTER CRITICALO /*关中断 IO2DIR= IO2DIR MASK DATA /*定义输出口其它为输入( ATA DATA为输入)*/ IOICLR= Addr Cs at P1 *控所硬盘引脚信号输出(输出高电平)*/ IOISET=reg *控所硬盘引脚信号输出(输出低电平)* IOOCLR= IDE RD /*读信号脚置低 读取数据” IOOSET= IDE RD IOISET= Addr cs at Pi 输出控制信号置高 OS EXIT CRITICALO: /*开中断
义如程序清单 1.5 所示。 程序清单 1.2 读取 ATA 设备寄存器函数 #ifdef ATA_BUS_AT_8bit uint16 SYS_PortIn(uint32 reg) /*8 位总线的读寄存器函数*/ { uint16 res ; OS_ENTER_CRITICAL(); /*关中断*/ IO2DIR = IO2DIR & MASK_DATA; /*定义输出口其它为输入(ATA_DATA 为输入)*/ IO1CLR = Addr_CS_at_P1; /*地址与片选信号都为低电平*/ IO1SET = reg; /*地址高电平位输出,完成地址的设置*/ /*读低字节*/ IO0CLR = IDE_RD; /*读信号脚置低*/ res = (uint8)((IO2PIN&ATA_DATA) >>16); /*读取数据*/ IO0SET = IDE_RD; /*使读信号为高*/ /*读高字节*/ if(reg==ATA_REG_DATA) /*如果读数据寄存器,读高字节*/ { IO0CLR = IDE_RD; /*读信号脚置低*/ res += (uint16)((IO2PIN&ATA_DATA)>>8); /*读取数据*/ IO0SET = IDE_RD; /*使读信号为高*/ } IO1SET = Addr_CS_at_P1; /*输出控制信号置高*/ OS_EXIT_CRITICAL(); /*开中断*/ return res; /*返回数值*/ } #else uint16 SYS_PortIn(uint32 reg) /*8 位总线的读寄存器函数*/ { uint16 res ; OS_ENTER_CRITICAL(); /*关中断*/ IO2DIR = IO2DIR & MASK_DATA; /*定义输出口其它为输入(ATA_DATA 为输入)*/ IO1CLR = Addr_CS_at_P1; /*控所硬盘引脚信号输出(输出高电平)*/ IO1SET = reg; /*控所硬盘引脚信号输出(输出低电平)*/ IO0CLR = IDE_RD; /*读信号脚置低*/ res = (uint16)(IO2PIN >>16); /*读取数据*/ IO0SET = IDE_RD; IO1SET = Addr_CS_at_P1; /*输出控制信号置高*/ OS_EXIT_CRITICAL(); /*开中断*/ return res; }
写ATA设备寄存器步骤如下: (1)关系统中断,预防在写寄存器操作中产生中断; (2)设置GPIO模拟ATA接口数据的引脚为输出状态,准备输出数据到设备数据线 (3)设置ATA设备寄存器的相应地址 (4)设置GPO模拟AIA接口数据的引脚的电平为要写到设备的值; (5)使写ATA设备寄存器信号引脚为低电平; (6)使写ATA设备寄存器信号引脚为高电平 (7)如果ATA设备(CF卡)是8位总线模式,并且操作的是数据寄存器(16位),则 需重复(3)、(4)、(5)步。 (8)取消ATA设备寄存器地址的选择。 (9)设置GPO模拟ATA接口的数据总线引脚为输入状态,释放总线。 (10)开系统中断。 LPC2210的GPIO引脚模拟写ATA设备寄存器的函数如程序清单1.3所示,ATA设备 各寄存器地址宏定义如程序清单1.5所示。 程序清单13写ATA设备寄存器函数 #ifdef ATA BUS aT &bit void SYS PortOut(uint32 reg, uint16 data) 使用8位数据总线 OS ENTER CRITICALO /关中断* IO2DIR=IO2DIR ATA DATA; 棒设置数据总线为输出* IoICLR= Addr Cs at PI 地址与片选信号都为低电平 IOISET=reg /地址高电平位输出,完成地址的设置* 章写低字节 IO2CLR=ATA DATA, /数据总线上输出全为低电平 IO2SET= data<<16 输出数据值为1的位* IO0CLR= IDE WR: /*写信号为低电平保持大于165nS*/ IOOSET= IDE WR: *写信号脚置高[与低>162ns]*/ if(reg==ATA REG DATA) /如果访问的寄存器为16位的数据寄存器* /*写高字节* IO2CLR= ATA DATA 数据线输出全为低电平 IOs SET= data<<8 输出高电平的数据位 IOOCLR= IDE WR /*写信号为低电平保持大于165nS* OOSET= IDE WR /*写信号脚置高[与低>162ns] IOiSET= Addr cs at Pl 输出控制信号置高 IO2DIR & MASK DATA. 使数据线为输入,降低功耗* OS EXIT CRITICALO: /开中断*/
#endif 写 ATA 设备寄存器步骤如下: (1) 关系统中断,预防在写寄存器操作中产生中断; (2) 设置 GPIO 模拟 ATA 接口数据的引脚为输出状态,准备输出数据到设备数据线; (3) 设置 ATA 设备寄存器的相应地址; (4) 设置 GPIO 模拟 ATA 接口数据的引脚的电平为要写到设备的值; (5) 使写 ATA 设备寄存器信号引脚为低电平; (6) 使写 ATA 设备寄存器信号引脚为高电平; (7) 如果 ATA 设备(CF 卡)是 8 位总线模式,并且操作的是数据寄存器(16 位),则 需重复(3)、(4)、(5)步。 (8) 取消 ATA 设备寄存器地址的选择。 (9) 设置 GPIO 模拟 ATA 接口的数据总线引脚为输入状态,释放总线。 (10) 开系统中断。 LPC2210 的 GPIO 引脚模拟写 ATA 设备寄存器的函数如程序清单 1.3 所示,ATA 设备 各寄存器地址宏定义如程序清单 1.5 所示。 程序清单 1.3 写 ATA 设备寄存器函数 #ifdef ATA_BUS_AT_8bit void SYS_PortOut(uint32 reg, uint16 data) /*使用 8 位数据总线*/ { OS_ENTER_CRITICAL(); /*关中断*/ IO2DIR = IO2DIR | ATA_DATA; /*设置数据总线为输出*/ IO1CLR = Addr_CS_at_P1; /*地址与片选信号都为低电平*/ IO1SET = reg; /*地址高电平位输出,完成地址的设置*/ /*写低字节*/ IO2CLR = ATA_DATA; /*数据总线上输出全为低电平*/ IO2SET = data<<16; /*输出数据值为 1 的位*/ IO0CLR = IDE_WR; /*写信号为低电平,保持大于 165nS*/ IO0SET = IDE_WR; /*写信号脚置高[与低>162ns]*/ if(reg==ATA_REG_DATA) /*如果访问的寄存器为 16 位的数据寄存器*/ { /*写高字节*/ IO2CLR = ATA_DATA; /*数据线输出全为低电平*/ IO2SET = data<<8; /*输出高电平的数据位*/ IO0CLR = IDE_WR; /*写信号为低电平,保持大于 165nS*/ IO0SET = IDE_WR; /*写信号脚置高[与低>162ns]*/ } IO1SET = Addr_CS_at_P1; /*输出控制信号置高*/ IO2DIR &= MASK_DATA; /*使数据线为输入,降低功耗*/ OS_EXIT_CRITICAL(); /*开中断*/ }