第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= data162ns]*/ if(reg==ATA REG DATA) /如果访问的寄存器为16位的数据寄存器* /*写高字节* IO2CLR= ATA DATA 数据线输出全为低电平 IOs SET= data162ns] 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 = data162ns]*/ if(reg==ATA_REG_DATA) /*如果访问的寄存器为 16 位的数据寄存器*/ { /*写高字节*/ IO2CLR = ATA_DATA; /*数据线输出全为低电平*/ IO2SET = data162ns]*/ } IO1SET = Addr_CS_at_P1; /*输出控制信号置高*/ IO2DIR &= MASK_DATA; /*使数据线为输入,降低功耗*/ OS_EXIT_CRITICAL(); /*开中断*/ }
void SYs PortOut(uint32 reg, uint16 data) 使用16位总线 OS ENTER CRITICALO /关中断* IO2DIR=IO2DIR ATA DATA 设置数据总线为输出* IoICLR= Addr cs at P1 地址与片选信号都为低电平制 lOISEL=reg: /地址高电平位输出完成地址的设置 IO2CLR=ATA DATA /数据总线上输出全为低电平 IO2SET= data162nsy* IOISET= Addr CS at P1; 输出控制信号置高* IO2DIR & MASK DATA. 使数据线为输入,降低功耗 OS EXIT CRITICALO: /开中断 #endif 开中断及关中断函数如程序清单14所示。 程序清单14开、关总中断函数 #ifndef UCOSll *关中断 nline OS ENTER CRITICAL( void) asm CPSR RO. RO. #NoInt MSR CPSR C RO /*开中断 inline OS EXIT CRITICAL(void) MRS RO CPSR RORO. #NoInt MSR CPSR C RO
#else void SYS_PortOut(uint32 reg, uint16 data) /*使用 16 位总线*/ { OS_ENTER_CRITICAL(); /*关中断*/ IO2DIR = IO2DIR | ATA_DATA; /*设置数据总线为输出*/ IO1CLR = Addr_CS_at_P1; /*地址与片选信号都为低电平*/ IO1SET = reg; /*地址高电平位输出,完成地址的设置*/ IO2CLR = ATA_DATA; /*数据总线上输出全为低电平*/ IO2SET = data162ns]*/ IO1SET = Addr_CS_at_P1; /*输出控制信号置高*/ IO2DIR &= MASK_DATA; /*使数据线为输入,降低功耗*/ OS_EXIT_CRITICAL(); /*开中断*/ } #endif 开中断及关中断函数如程序清单 1.4 所示。 程序清单 1.4 开、关总中断函数 #ifndef UCOSII (1) #define NoInt 0x80 /* 关中断 */ __inline OS_ENTER_CRITICAL(void) { __asm { MRS R0, CPSR ORR R0, R0, #NoInt MSR CPSR_c, R0 } } /* 开中断 */ __inline OS_EXIT_CRITICAL(void) { __asm { MRS R0, CPSR BIC R0, R0, #NoInt MSR CPSR_c, R0 }
#endif (1)如果驱动用于uOSH操作系统,则不需要编译这两个开、关中断函数,因为在 uCOS中已定义了这两个函数 SYS PortIn0和 SYS PartOut(函数通过使用程序清单15中定义的ATA设备寄存器的地 址的宏作为参数,实现对ATA设备各寄存器的读写操作。 ZLG/CF驱动读写ATA设备寄存器的函数如程序清单16所示 程序清单15设备寄存器地址宏定义 /*GPI0引脚影射寄存器地址*/ Define ATA REG DATA IDE CSI /*数据寄存器* #define ATA REG ERR (IDE CSI IDE AO) /*读错误寄存器* #define ATA REG FEATURE (DE CSI IDE AO) /*写功能寄存器* Define ATA REG SECCNT (IDE CSI IDE Al) /*扇区计数器*/ Define ATA REG SECTOR (IDE CSI IDE Al+ IDE AO) /*扇区号*/ #define ATA REG CYLI LOW (IDE CSI IDE A2) /*柱面低8位*/ #define ATA REG CYLI HIGH (IDE CSI IDE A2+ IDE AO) /*柱面高8位* Define ATA REG DEVICE HEAD (IDE CSI IDE A2 IDE Al /*选择主从,模式,磁头* Define ATA REG COMMAND (IDE_CS1+IDE_A2+IDE_A1+IDEA0)/*写命令寄存器 #define ATA REG STATUS ( IDE CSI+IDE_A2+IDE_A1+IDEA0)/*读状态寄存器* Define ATA REG CONTROL (DE CSO+ IDE A2 IDE Al) /*写控制寄存器* Define ATA REG ASTATUS (IDE CSO IDE A2 IDE Al) *读辅助状态寄存器*/ 程序清单16读写设备相关寄存器接口函数 /驱动与硬件对ATA设备寄存器操作接口* #define GetDatao SYS PortIn(ATA REG DATA) /读数据寄存器,与驱动接口考 SYS PortOut(ATA REG DATA, X) /写数据寄存器,与驱动接口 #define getERRO SYS PortIn(ATA REG ERR) /读错误寄存器,与驱动接口* # define set feature(x) SYS Potou( ATA REG FEATUREX)/写特征寄存器,与驱动接口 #define GetSECCNTO SYS PortIn(ATA REG SECCNT) /读扇区计数寄存器,与驱动接口啊 #define SetsECCNT(x) SYS PortOut(ATA REG SECCNT, X) /写扇区计数寄存器,与驱动接口 #define GetSectorO SYS PortIn(ATA REG SECTOR) *读扇区寄存器与驱动接口* define SetSectort(x) SYS PortOut( ATA REG SECTOR. X)写扇区寄存器与驱动接口 # define GetCylinderLowO SYs_ Portin( ATA REG CYLINDER LOW)/读柱面低寄存器,与驱动接口 # define SetCylinderLow(x) SYS Partout( ATA REG_CYLⅠNDER_LOW,xy写柱面低寄存器与驱动接口 #define GetCylinderHighO SYS PortIn(ATA REG CYLI HIGH /读柱面高8位寄存器,与驱动接口* # define SetCylinderHigh(x)SYS_ Partout( ATA REG CYLI HIGHX)/写柱面高8位寄存器,与驱动接口* # define GetDeviceHeado SYS PortIn( ATA REG DEⅤ CE HEAD)/读设备磁头寄存器,与驱动接口 # define SetDeviceHead(x) SYS PartOut( ATA REG DEYⅥ CE HEAD,x)/*写设备磁头寄存器,与驱动接口 SYS PortIn(ATA REG STATUS) /*读状态寄存器与驱动接口* # define setCommand(x)SYS_ Potou( ATA REG_ COMMAND,x)写命令寄存器与驱动接口 硬件复位函数
} #endif (1) 如果驱动用于 uC/OS-II 操作系统,则不需要编译这两个开、关中断函数,因为在 uC/OS-II 中已定义了这两个函数。 SYS_PortIn()和SYS_PortOut()函数通过使用程序清单1.5中定义的ATA设备寄存器的地 址的宏作为参数,实现对 ATA 设备各寄存器的读写操作。 ZLG/CF 驱动读写 ATA 设备寄存器的函数如程序清单 1.6 所示。 程序清单 1.5 设备寄存器地址宏定义 /*GPIO 引脚影射寄存器地址*/ #define ATA_REG_DATA IDE_CS1 /*数据寄存器*/ #define ATA_REG_ERR (IDE_CS1 + IDE_A0) /*读错误寄存器*/ #define ATA_REG_FEATURE (IDE_CS1 + IDE_A0) /*写功能寄存器*/ #define ATA_REG_SECCNT (IDE_CS1 + IDE_A1) /*扇区计数器*/ #define ATA_REG_SECTOR (IDE_CS1 + IDE_A1 + IDE_A0) /*扇区号*/ #define ATA_REG_CYLI_LOW (IDE_CS1 + IDE_A2) /*柱面低 8 位*/ #define ATA_REG_CYLI_HIGH (IDE_CS1 + IDE_A2 + IDE_A0) /*柱面高 8 位*/ #define ATA_REG_DEVICE_HEAD (IDE_CS1 + IDE_A2 + IDE_A1) /*选择主从,模式,磁头*/ #define ATA_REG_COMMAND (IDE_CS1 + IDE_A2 + IDE_A1 + IDE_A0) /*写命令寄存器*/ #define ATA_REG_STATUS (IDE_CS1 + IDE_A2 + IDE_A1 + IDE_A0) /*读状态寄存器*/ #define ATA_REG_CONTROL (IDE_CS0 + IDE_A2 + IDE_A1) /*写控制寄存器*/ #define ATA_REG_ASTATUS (IDE_CS0 + IDE_A2 + IDE_A1) /*读辅助状态寄存器*/ 程序清单 1.6 读写设备相关寄存器接口函数 /*驱动与硬件对 ATA 设备寄存器操作接口*/ #define GetData() SYS_PortIn(ATA_REG_DATA) /*读数据寄存器,与驱动接口*/ #define SetData(x) SYS_PortOut(ATA_REG_DATA,x) /*写数据寄存器,与驱动接口*/ #define GetERR() SYS_PortIn(ATA_REG_ERR) /*读错误寄存器,与驱动接口*/ #define SetFeature(x) SYS_PortOut(ATA_REG_FEATURE,x) /*写特征寄存器,与驱动接口*/ #define GetSECCNT() SYS_PortIn(ATA_REG_SECCNT) /*读扇区计数寄存器,与驱动接口*/ #define SetSECCNT(x) SYS_PortOut(ATA_REG_SECCNT,x) /*写扇区计数寄存器,与驱动接口*/ #define GetSector() SYS_PortIn(ATA_REG_SECTOR) /*读扇区寄存器,与驱动接口*/ #define SetSector(x) SYS_PortOut(ATA_REG_SECTOR,x) /*写扇区寄存器,与驱动接口*/ #define GetCylinderLow() SYS_PortIn(ATA_REG_CYLINDER_LOW) /*读柱面低寄存器,与驱动接口*/ #define SetCylinderLow(x) SYS_PortOut(ATA_REG_CYLINDER_LOW,x)/*写柱面低寄存器,与驱动接口*/ #define GetCylinderHigh() SYS_PortIn(ATA_REG_CYLI_HIGH) /*读柱面高 8 位寄存器,与驱动接口*/ #define SetCylinderHigh(x) SYS_PortOut(ATA_REG_CYLI_HIGH,x) /*写柱面高 8 位寄存器,与驱动接口*/ #define GetDeviceHead() SYS_PortIn(ATA_REG_DEVICE_HEAD) /*读设备磁头寄存器,与驱动接口*/ #define SetDeviceHead(x) SYS_PortOut(ATA_REG_DEVICE_HEAD,x)/*写设备磁头寄存器,与驱动接口*/ #define GetStatus() SYS_PortIn(ATA_REG_STATUS) /*读状态寄存器,与驱动接口*/ #define SetCommand(x) SYS_PortOut(ATA_REG_COMMAND,x) /*写命令寄存器,与驱动接口*/ 2.硬件复位函数
系统中定义了 IDE RST引脚控制ATA设备的硬件复位。如程序清单1.7所示 程序清单17硬件复位函数 /率事率率事事摩率率率率事事布摩率*率 函数名称 SYS Idehard Reset 奉*功能描述:ATA设备硬件复位 无 输出:无 *全局变量 *调用模块: SYS WaitInUSO,等待微秒函数。 void SYS IdeHardReset( void) IOCLR= IDE RST 复位引脚置低* SYS WaitInUS(30) 延时大于25微秒考 IOSET= IDE RST. /复位引脚置高* SYS WaitinUS(5000); 延时大于2毫秒 /率事事**率率事事市事*和率率事事事市率布*率率事布事事市率率布率市事市率*率*事事 函数名称: SYS WaitInUS *功能描述:延时等级约1微秒函数,该函数根据系统时间不同与不同,但不应少到1微秒 奉*输入: times,延时时间等级 *全局变量 **调用模块 void SYS WaitInUS(uint32 times) for(: O<times times--) for(=0,c<5;c++), 3.设备检测函数 该函数用于检测CF卡插入及拔出, ZLG/CE驱动要求系统必须提供该函数,即使系统 中没有设计检测CF卡插入及拔出功能。 4.模拟ATA接口初始化函数 使用LPC2210的GPI0模拟ATA接口,定义了各引脚为输入或输出(见表1.1)。在使用 我们定义好的引脚前,必须对LPC2210相关的寄存器进行配置。详见1.1.3小节。 113LPC2210相关寄存器配置 使用GPIO模拟ATA接口相关的寄存器只有几个: PINSEL1、 PINSEL2、 lOODIR、 IOIDIR、IO2DIR、IO0SET、IO0CLR、 LOISET、 IOICLR、IO2SET、IO2CLR等 P|NSEL1寄存器
系统中定义了 IDE_RST 引脚控制 ATA 设备的硬件复位。如程序清单 1.7 所示。 程序清单 1.7 硬件复位函数 /******************************************************************************************* ** 函数名称: SYS_IdeHardReset ** 功能描述: ATA 设备硬件复位 ** 输 入: 无 ** 输 出: 无 ** 全局变量: ** 调用模块: SYS_WaitInUS(),等待微秒函数。 *******************************************************************************************/ void SYS_IdeHardReset(void) { IOCLR = IDE_RST; /*复位引脚置低*/ SYS_WaitInUS(30); /*延时大于 25 微秒*/ IOSET = IDE_RST; /*复位引脚置高*/ SYS_WaitInUS(5000); /*延时大于 2 毫秒*/ } /******************************************************************************************* ** 函数名称: SYS_WaitInUS ** 功能描述: 延时等级约 1 微秒函数,该函数根据系统时间不同与不同,但不应少到 1 微秒。 ** 输 入: times,延时时间等级 ** 输 出: 无 ** 全局变量: ** 调用模块: *******************************************************************************************/ void SYS_WaitInUS(uint32 times) { uint32 c; for(;0<times;times--) for(c=0;c<5;c++); } 3.设备检测函数 该函数用于检测 CF 卡插入及拔出,ZLG/CF 驱动要求系统必须提供该函数,即使系统 中没有设计检测 CF 卡插入及拔出功能。 4.模拟 ATA 接口初始化函数 使用 LPC2210 的 GPIO 模拟 ATA 接口,定义了各引脚为输入或输出(见表 1.1)。在使用 我们定义好的引脚前,必须对 LPC2210 相关的寄存器进行配置。详见 1.1.3 小节。 1.1.3 LPC2210 相关寄存器配置 使用 GPIO 模拟 ATA 接口相关的寄存器只有几个: PINSEL1、PINSEL2、IO0DIR、 IO1DIR、IO2DIR、IO0SET、IO0CLR、IO1SET、IO1CLR、IO2SET、IO2CLR 等。 z PINSEL1 寄存器
表1.2描述了 PINSELI相关位的配置。 表12 PINSEL1相关位的配量 PINSEL1(0x002c004)描述 配置值(二进制) 引脚P0.16根据其它需要定义 使引脚P0.19:17为GPI0 000000 13:8 使引脚P0.22:20为GPI0 15:14 引脚P0.23根据其它需要定义 3:16 脚P0.27:24根据其它需要定义 XXXXXXXX 匚3:2411031:28根据其它需要定义 xxXXXXXX P|NSEL2寄存器 表1.3描述了 PINSEL2相关位的配置。 表13P|NSEL2相关位的配量 PINSEL2(0X002C014)描述 配置值(二进制) 1:0 保留 使引脚P1.36:26为调试端口 使引脚P1.25为GPI0 使P2.31:16为非数据总线D31:16 7:6 根据其它需要设置 l1:8 假设使用片外RAM、 FLASH,使用低16位总线 假设使用片外RAM、 FLASH,使能W、CS1 根据其它需要设置 19:16 根据其它需要设置 使能P2.29:28,其它根据需要设置 假设使用片外RAM、 FLASH,使能A0 27:24假设使用片外RMRA8B,使能AL:23 XXXX 保留 RI: PINSEL2-(PINSEL2 Oxof8cf9c0)10x00000014. 100D0R寄存器 根据表1.1的描述,配置I00IR寄存器的位,见表14。 表14|O0D|R寄存配置 OODIR 配置值(二进制) 7:0 ‖根据其它需要设置 XXXXXXXX 根据其它需要设置 XXXXXXXX 23:16 配置引脚P0.17、P0.19、P0.21为输出 Xo10101X 配置引脚P0.18、P0.20、P0.22为输入 31:24 根据其它需要设置 XXXXXXXX
表 1.2 描述了 PINSEL1 相关位的配置。 表 1.2 PINSEL1 相关位的配置 PINSEL1(0xE002C004) 描述 配置值(二进制) 1:0 引脚 P0.16 根据其它需要定义 XX 7:2 使引脚 P0.19:17 为 GPIO 000000 13:8 使引脚 P0.22:20 为 GPIO 000000 15:14 引脚 P0.23 根据其它需要定义 XX 23:16 引脚 P0.27:24 根据其它需要定义 XXXXXXXX 31:24 引脚 P0.31:28 根据其它需要定义 XXXXXXXX z PINSEL2 寄存器 表 1.3 描述了 PINSEL2 相关位的配置。 表 1.3 PINSEL2 相关位的配置 PINSEL2(0xE002C014) 描述 配置值(二进制) 1:0 保留 00 3:2 使引脚 P1.36:26 为调试端口 使引脚 P1.25 为 GPIO 01 5:4 使 P2.31:16 为非数据总线 D31:16 01 7:6 根据其它需要设置 XX 11:8 假设使用片外 RAM、FLASH,使用低 16 位总线 假设使用片外 RAM、FLASH,使能 WE、CS1 X00X 15:12 根据其它需要设置 XXXX 19:16 根据其它需要设置 00XX 23:20 使能 P2.29:28,其它根据需要设置; 假设使用片外 RAM、FLASH,使能 A0 X000 27:24 假设使用片外 RAM、FLASH,使能 A1:23 XXXX 31:28 保留 0000 即:PINSEL2 = (PINSEL2 & 0x0f8cf9c0) | 0x00000014。 z IO0DIR 寄存器 根据表 1.1 的描述,配置 IO0DIR 寄存器的位,见表 1.4。 表 1.4 IO0DIR 寄存器配置 IO0DIR 描述 配置值(二进制) 7:0 根据其它需要设置 XXXXXXXX 15:8 根据其它需要设置 XXXXXXXX 23:16 配置引脚 P0.17、P0.19、P0.21 为输出 配置引脚 P0.18、P0.20、P0.22 为输入 X010101X 31:24 根据其它需要设置 XXXXXXXX
RI: IOODIR=(PINSEL2& Oxff81ffff)I OX002a0000 101D|R寄存器 根据表1.1的描述,配置I01DIR寄存器的位,见表1.5 表15|01DR寄存器配置 01D|R 描述 配置值(二进制) 7:0 根据其它需要设置 XXXXXXXX 根据其它需要设置 23:16 配置引脚P1.16、P1.17、P1.18、P1.19 lX0l1111 P1.20、P1.23输出 配置引脚P1.21为输入 31:24 配置P1.24、P1.25为输入 XXXXXXOO 根据其它需要设置 102DR寄存器 根据表1.1的描述,配置IO2DIR寄存器的位,见表1.6 表16102D|R寄存器配置 O2DIR 描述 配置值(二进制) 7:0 根据其它需要设置 根据其它需要设置 23:16 读操作时设为输入,写操作时设为输出,初00 始化时设为输入 读操作时设为输入,写操作时设为输出,初 00000000 始化时设为输入 ●100sET、I00LR、101SET、01CLR、102SET、|02CLR寄存器 改变各个GPI0输出引脚的状态位是通过I00SET、I00LR、IO1SET、I01CLR、I02SET、 I02CLR等寄存器设置的。初始化设置如表17所示,在读写ATA设备寄存器函数中分别 进行适当的设置(如程序清单1.2和程序清单1.3所示)。 表17初始化时GP0输出引脚电平设置 寄存器描述配置值(十六进制) 初始化P0.17、P0.19、P0.21输出高电平 002A0000H IOOCLR 初始化时不需要配置 101SET P1.19、P1.20输出高电平 00l80000H I01 CLR P1.16、P1.17、P1.18、P1.23输出低电平 00870000H 初始化时引脚P2.31:16为输入,该寄存器不需要配置 102CLR|初始化时引脚P.31:16为输入,该寄存器不需要配置 根据以上寄存器的描述,使用模拟ATA接口前需对以上寄存器进行设置,对相关寄存器 的设置也就是模拟ATA接口总线的初始化。再根据表1.1描述各引脚的输入或输出特性,设
即:IO0DIR= (PINSEL2 & 0xff81ffff) | 0x002a0000。 z IO1DIR 寄存器 根据表 1.1 的描述,配置 IO1DIR 寄存器的位,见表 1.5。 表 1.5 IO1DIR 寄存器配置 IO1DIR 描述 配置值(二进制) 7:0 根据其它需要设置 XXXXXXXX 15:8 根据其它需要设置 XXXXXXXX 23:16 配置引脚 P1.16、P1.17、P1.18、P1.19、 P1.20、P1.23 输出 配置引脚 P1.21 为输入 1X011111 31:24 配置 P1.24、P1.25 为输入; 根据其它需要设置 XXXXXX00 z IO2DIR 寄存器 根据表 1.1 的描述,配置 IO2DIR 寄存器的位,见表 1.6。 表 1.6 IO2DIR 寄存器配置 IO2DIR 描述 配置值(二进制) 7:0 根据其它需要设置 XXXXXXXX 15:8 根据其它需要设置 XXXXXXXX 23:16 读操作时设为输入,写操作时设为输出,初 始化时设为输入 00000000 31:24 读操作时设为输入,写操作时设为输出,初 始化时设为输入 00000000 z IO0SET、IO0CLR、IO1SET、IO1CLR、IO2SET、IO2CLR 寄存器 改变各个 GPIO 输出引脚的状态位是通过 IO0SET、IO0CLR、IO1SET、IO1CLR、IO2SET、 IO2CLR 等寄存器设置的。初始化设置如表 1.7 所示,在读写 ATA 设备寄存器函数中分别 进行适当的设置(如程序清单 1.2 和程序清单 1.3 所示)。 表 1.7 初始化时 GPIO 输出引脚电平设置 寄存器 描述 配置值(十六进制) IO0SET 初始化 P0.17、P0.19、P0.21 输出高电平 002A0000H IO0CLR 初始化时不需要配置 - IO1SET P1.19、P1.20 输出高电平 00180000H IO1CLR P1.16、P1.17、P1.18、P1.23 输出低电平 00870000H IO2SET 初始化时引脚 P2.31:16 为输入,该寄存器不需要配置 - IO2CLR 初始化时引脚 P2.31:16 为输入,该寄存器不需要配置 - 根据以上寄存器的描述,使用模拟 ATA 接口前需对以上寄存器进行设置,对相关寄存器 的设置也就是模拟 ATA 接口总线的初始化。再根据表 1.1 描述各引脚的输入或输出特性,设