📄 test.c
字号:
//*****************************************************************
// The Code is for TrueIDE MODE of CF Card
// CF-ATA-4 Command Set
// CF+ and CompactFlash Specification Revision 3.0
// Programed by HeHu (Taiyuan Univ. of Tech.)
// Email : hoo_hee@msn.com
// Data : 2005-8-31
// Compile Enviroment : IAR Embeded Workbench IDE 3.10A
// Firmware : MSP430F1491
// Kingston CompactFlash Digital Memory Card(128MB)
// Embedded OS : uC/OS-II(Jean J.Labrosse Reserved)
//*****************************************************************
#include <msp430x14x1.h>
//*******************************************************************************
// Hardware Connection Description
// D7~D0 to MSP430F149 P5.7~P5.0
// A02~A00 to MSP430F149 P4.2~P4.0
// /CS1 to MSP430F149 P4.4
// /CS0 to MSP430F149 P4.3
// /IORD to MSP430F149 P4.5
// /IORW to MSP430F149 P4.6
// /RESET to MSP430F149 P4.7
// CSEL to GND
// /ATASEL to GND
// /VS1 to MSP430F149 P2.0
// IORDY to MSP430F149 P2.1
// INTRQ to MSP430F149 P2.4
// /DASP is connected to a LED in series with a 510 resistor to VCC.
// When the CF Card is inactive, LED is OFF; when CF Card is active, LED is ON.
#define CF_DATA_DIR P5DIR
#define CF_DATA_OUT P5OUT
#define CF_DATA_IN P5IN
#define CF_ADDR_DIR P4DIR
#define CF_ADDR_OUT P4OUT
#define CF_CONTROL_DIR P2DIR
#define CF_CONTROL_OUT P2OUT
#define RST BIT7 //P4
#define CS1 BIT4 //P4
#define CS0 BIT3 //P4
#define A2 BIT2 //P4
#define A1 BIT1 //P4
#define A0 BIT0 //P4
#define WR BIT6 //P4
#define RD BIT5 //P4
#define VS1 BIT0 //P2
#define IORDY BIT1 //P2
#define DASP BIT2 //P2
#define INTRQ BIT4 //P2
//*******************************************************************************
typedef unsigned char uint8; /* 无符号8位整型变量 */
typedef signed char int8; /* 有符号8位整型变量 */
typedef unsigned int uint16; /* 无符号16位整型变量 */
typedef signed int int16; /* 有符号16位整型变量 */
typedef unsigned long uint32; /* 无符号32位整型变量 */
typedef signed long int32; /* 有符号32位整型变量 */
#define ATA_REG_DATA CS1 /*数据寄存器*/
#define ATA_REG_ERR (CS1 + A0) /*读错误寄存器*/
#define ATA_REG_FEATURE (CS1 + A0) /*写功能寄存器*/
#define ATA_REG_SECCNT (CS1 + A1) /*扇区计数器*/
#define ATA_REG_SECTOR (CS1 + A1 + A0) /*扇区号*/
#define ATA_REG_CYLINDER_LOW (CS1 + A2) /*柱面低8位*/
#define ATA_REG_CYLINDER_HIGH (CS1 + A2 + A0) /*柱面高8位*/
#define ATA_REG_DEVICE_HEAD (CS1 + A2 + A1) /*选择主从,模式,磁头*/
#define ATA_REG_COMMAND (CS1 + A2 + A1 + A0)/*写命令寄存器*/
#define ATA_REG_STATUS (CS1 + A2 + A1 + A0)/*读状态寄存器*/
#define ATA_REG_CONTROL (CS0 + A2 + A1) /*写控制寄存器*/
#define ATA_REG_ASTATUS (CS0 + A2 + A1) /*读辅助状态寄存器*/
#define TRUE 1
#define FALSE 0
#define OS_EXIT_CRITICAL() _EINT()
#define OS_ENTER_CRITICAL(); _DINT()
/*驱动与硬件对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) /*读柱面低8位寄存器,与驱动接口*/
#define SetCylinderLow(x) SYS_PortOut(ATA_REG_CYLINDER_LOW,x) /*写柱面低8位寄存器,与驱动接口*/
#define GetCylinderHigh() SYS_PortIn(ATA_REG_CYLINDER_HIGH) /*读柱面高8位寄存器,与驱动接口*/
#define SetCylinderHigh(x) SYS_PortOut(ATA_REG_CYLINDER_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) /*写命令寄存器,与驱动接口*/
#define GetAStatus() SYS_PortIn(ATA_REG_ASTATUS) /*读辅助状态寄存器,与驱动接口*/
#define SetControl(x) SYS_PortOut(ATA_REG_CONTROL,x) /*写控制寄存器,与驱动接口*/
/****************************************************************************************/
/** 以下为本驱动定义部份,用户不需改动 */
/****************************************************************************************/
/*ATA 指令代码*/
#define IDE_CMD_ATAPI_RESET 0x08
#define IDE_CMD_RECALIBRATE 0x10
#define IDE_CMD_READ 0x20 // 读扇区命令
#define IDE_CMD_WRITE 0x30 // 写扇区命令
#define IDE_CMD_VERIFY 0x40
#define IDE_CMD_SEEK 0x70
#define IDE_CMD_EXEC_DIAGNOSE 0x90
#define IDE_CMD_SET_DRIVE_PARAMETERS 0x91
#define IDE_CMD_READ_MULTIPLE 0xC4 // 多扇区读
#define IDE_CMD_WRITE_MULTIPLE 0xC5 // 多扇区写
#define IDE_CMD_SET_MULTIPLE 0xC6
#define IDE_CMD_READ_DMA 0xC8
#define IDE_CMD_WRITE_DMA 0xCA
#define IDE_CMD_GET_MEDIA_STATUS 0xDA
#define IDE_CMD_STANDBY_IMMEDIATE 0xE0 // Standby Immediate
#define IDE_CMD_IDLE_IMMEDIATE 0xE1 // Idle Immediate
#define IDE_CMD_SETFEATURES 0xEF
#define IDE_CMD_IDENTIFY 0xEC
#define IDE_CMD_MEDIA_EJECT 0xED
/*状态寄存器相关位*/
#define ATA_STAT_REG_ERR 0x01 /*设备发生了错误*/
#define ATA_STAT_REG_IDX 0x02 /**/
#define ATA_STAT_REG_CORR 0x04 /**/
#define ATA_STAT_REG_DRQ 0x08 /*有数据传输请求*/
#define ATA_STAT_REG_DSC 0x10 /**/
#define ATA_STAT_REG_DF 0x20 /**/
#define ATA_STAT_REG_DRDY 0x40 /*设备准备好*/
#define ATA_STAT_REG_BSY 0x80 /*设备忙*/
#define ATA_STAT_BSY_DRDY (ATA_STAT_REG_BSY+ATA_STAT_REG_DRDY)
#define ATA_STAT_BSY_DRQ (ATA_STAT_REG_BSY+ATA_STAT_REG_DRQ)
/*设备磁头寄存器*/
#define ATA_DevReg_DEV0 0x00 /*设备为主盘*/
#define ATA_DevReg_DEV1 0x10 /*设备为从盘*/
#define ATA_DevReg_b5 0x20 /*保留位,为1*/
#define ATA_DevReg_LBA 0x40 /*模式选择位*/
#define ATA_DevReg_b7 0x80 /*保留位,为1*/
/*控制寄存器*/
#define CF_SOFT_RESET 0x04 /*软件复位有效*/
#define CF_DISABLE_INT 0x00 /*禁能中断*/
#define CF_ENABLE_INT 0x02 /*使能中断*/
/*错误代码由16位二进制数组成,低8位与ATA错误寄存器一致,高8位自定义*/
#define ATA_EER_REG_AMNF 0x01 /*一般错误*/
#define ATA_EER_REG_ABRT 0x04 /*指令无效出错*/
#define ATA_EER_REG_IDNF 0x10 /*寻扇区地址出错*/
#define ATA_EER_REG_UNC 0x40 /*发生了不可纠正的错误*/
#define ATA_EER_REG_BBK 0x80 /*发现错误块*/
/*自定义*/
#define CARD_IS_FALSE 0x00ff /*CF卡不存在或无效*/
#define CARD_IS_TRUE 0x0000 /*CF卡有效*/
#define CARD_TIMEOUT 0x0100 /*对CF卡操作超时出错*/
#define THIS_DEVICE ((ATA_DevReg&0x10)>>4) /*当前操作的设备,ATA_SelectDevice函数选择了主或从设备,通过该操作可以确定刚才选定的设备*/
/*设备识别信息*/
/*全部设备信息*/
typedef struct _IDENTIFY_DATA {
uint16 GeneralConfiguration; // 00 普通设置-CF卡标志0x848A
uint16 NumberOfCylinders; // 1 默认柱面数
uint16 Reserved1; // 2
uint16 NumberOfHeads; // 3 默认磁头数
uint16 UnformattedBytesPerTrack; // 4 在2.0规范已不使用
uint16 UnformattedBytesPerSector; // 5 在2.0规范已不使用
uint16 SectorsPerTrack; // 6 每磁道默认扇区数
uint32 SectorsPerCard; // 7-8 每卡扇区数(Word 7=MSW,Word 8=LSW)
uint16 VendorUnique; // 9 在2.0规范已不使用
uint16 SerialNumber[10]; // 10-19 ASCII序列号(靠右填写)
uint16 BufferType; // 20 在2.0规范已不使用
uint16 BufferSectorSize; // 21 在2.0规范已不使用
uint16 NumberOfEccBytes; // 22 读/写长指令时的ECC字节数
uint16 FirmwareRevision[4]; // 23-26 ASCII固件版本。大端格式
uint16 ModelNumber[20]; // 27-46 ASCII模式号(靠左填写),大端格式
uint16 MaximumBlockTransfer; //*47 多重 读/写指令最大扇区号。
uint16 Reserved2; // 48
uint16 Capabilities; // 49
uint16 Reserved3; // 50
uint16 PioCycleTimingMode; //*51 PIO数据传输周期时序模式
uint16 DmaCycleTimingMode; // 52 在2.0规范已不使用
uint16 TranslationFieldsValid; // 53 0位为1,Word54 to 58 有效;1位为1,Word64 to 70 有效
uint16 NumberOfCurrentCylinders; // 54 当前柱面数
uint16 NumberOfCurrentHeads; // 55 当前磁头数
uint16 CurrentSectorsPerTrack; // 56 当前每磁道扇区数
uint32 CurrentSectorCapacity; // 57-58 当前扇区容量(LBAs)(Word 58=MSW,Word 57=LSW)
uint16 CurrentMultiSectorSetting; //*59 位8为1,则位0-7,指出可多扇区读写的扇区数
uint32 UserAddressableSectors; // 60-61 LAB模式下可被寻址的扇区数
uint16 Reserved4[2] ; // 62-63
uint16 AdvancedPIOModes ; // 64 在2.0规范使用
uint16 Reserved6[2] ; // 65-66
uint16 MinimumPIOCycleTime; // 67 非流控制下最小PIO传输周期时间
uint16 MinimumPIOCycleTimeIORDY; // 68 IORDY流控制小最小PIO传输周期时间
uint16 Reserved7[10]; // 69-79
uint32 AtaVersion; // 80-81 CF卡返回0
uint16 FeaturesCommandSupported[3]; // 82-84 特征/命令集技持
uint16 FeaturesCommandEnabled[3]; // 85-87 特征/命令集使能
uint16 Reserved8; // 88
uint16 MajorRevision; // 89 安全单位完全擦除的时间要求
uint16 MinorRevision; // 90 增强型安全单位完全擦除的时间要求
uint16 PowerManagementValue; // 91 当前高级电源管理值 // 91
uint16 Reserved9[36]; // 92-127
uint16 SecurityStatus; // 128 安全状态
uint16 VendorUniqueBytes[32]; // 129-159
uint16 PowerRequirementDescription; // 160 电源要求描述
uint16 Reserved10; // 161
uint16 KeyManagementSupported; // 162 按键管理表
uint16 Reserved11[83]; // 163-255
} CF_IDENTIFY_DATA, *PCF_IDENTIFY_DATA;
/*设备基本信息*/
typedef struct _ATA_IDENTIFY_DATA {
uint16 NumberOfCylinders; // 1 默认柱面数
uint16 NumberOfHeads; // 3 默认磁头数
uint16 SectorsPerTrack; // 6 每磁道默认扇区数
uint32 CurrentSectorCapacity; // 57-58 当前扇区容量(LBAs)(Word 58=MSW,Word 57=LSW)
} ATA_IDENTIFY_DATA, *PATA_IDENTIFY_DATA;
/*设备信息结构*/
typedef struct {
uint8 ATAIsOK; /*设备正常为1,无效或有错为0*/
uint16 ERRCODE; /*设备出错代码*/
int32 ERRSECTOR; /*读写扇区是出错的扇区号*/
ATA_IDENTIFY_DATA INFODATA; /*设备的基本信息*/
}ATADEVICE,*PATADEVICE;
#define NULL 0
#define MAX_DEVICE 2 /*定义设备数,由于只有主和从设备,所以最大值为2*/
#define TIMEOUTSET 0xffff /*超时响应设备(与CPU的速度有关,没有准确的时间)*/
ATADEVICE ATA[MAX_DEVICE]; /*设备识别信息识别结构,及设备的状态*/
uint8 ATA_DevReg ; /*设备磁头寄存器值,通过该寄存器可以确定*/
/******************************************************************************************/
/*相关函数原型*/
/******************************************************************************************/
//****************************************************************************************
/*用户使用函数*/
void ATA_INI(void); /*总线设置与初始化,ATA设备初始化*/
void ATA_FindIDEDevice(void); /*硬件复位,查找IDE设备,并初始化*/
uint8 ATA_IdleImmediate(uint8 Device); /*立即进入空闲状态(硬盘转动)*/
uint8 ATA_StandbyImmediate(uint8 Device); /*立即进入待机状态(硬盘停转)*/
uint8 ATA_ReadSector(uint8 Device,uint16 *Buffer,uint32 Sector,uint8 count);
/*读出扇区数据函数*/
uint8 ATA_WriteSector(uint8 Device,uint16 * Buffer, uint32 Sector ,uint8 count);
/*写入设备扇区数据函数*/
uint8 ATA_IdentifyDrive(uint8 Device,void *PTR); /*获取设备信息*/
//****************************************************************************************
/*驱动内部使用函数*/
uint8 ATA_IssueIDEIdentify(uint8 Device); /*设备识别,获取设备基本信息*/
uint8 ATA_SetFeature(uint8 Device); /*设备总线特性设置*/
void ATA_WriteSetting(uint32 Sectors , uint8 Count); /*写IDE多数扇区数据*/
void ATA_ReadSetting(uint32 Sectors , uint8 Count); /*写IDE多数扇区数据*/
void ATA_WriteData512B(uint16 * Buffer); /*连续写512字节数据*/
void ATA_ReadData512B(uint16 * Buffer); /*连续读512字节数据*/
/*硬件相关函数*/
void SYS_BusIni(void); /*ATA总线初始化函数*/
uint16 SYS_PortIn(uint8 reg); /*从ATA设备指定的寄存器读出一个字(2字节)*/
void SYS_PortOut(uint8 reg,uint16 data); /*从ATA设备指定的寄存器写入一个字*/
void SYS_IdeHardReset(void); /*硬件复位*/
uint8 SYS_HaveCard(void); /*检测CF卡是否存在*/
void SYS_WaitInUS(uint32 times);
uint8 temp1,temp2,temp3,temp4,temp5,temp6,temp7;
uint16 temp16;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
BCSCTL1= RSEL2 + RSEL1 + RSEL0; // 我没接8MHz晶体,所以用DCO最高频率提供MCLK
DCOCTL = DCO2 + DCO1 + DCO0;
SYS_BusIni();
/*探测设备是否存在函数测试*/
if(SYS_HaveCard()) //探测CF卡是否存在
{ /*复位及读寄存器函数测试*/
SYS_IdeHardReset(); //ATA设备硬件复位
SYS_WaitInUS(48000); //复位后ATA设备需在480mS内完成硬件初始化和自检
temp1 = GetSECCNT(); //复位该寄存器的值为0x01
if(0x01!=temp1)
{
while(1); //读函数有误或设备无效
}
temp2 = GetSector(); //复位该寄存器的值为0x01
temp3 = GetCylinderLow(); //复位该寄存器的值为0x00
temp4 = GetCylinderHigh(); //复位该寄存器的值为0x00
temp5 = GetDeviceHead(); //复位该寄存器的值为0x00
temp6 = GetStatus(); //复位该寄存器的值为0x50
temp7 = GetAStatus(); //复位该寄存器的值为0x50
/*写函数测试*/
SetSector(0xaa); //写数据寄存器
temp16 = GetSector();
if(0xaa!=temp16) //比较写入与读出的值
{
while(1); //写函数有误
}
}
while(1);
}
void SYS_BusIni(void)
{
CF_ADDR_DIR |= CS1 +CS0 + A2 + A1 + A0 + WR +RD + RST;
CF_CONTROL_DIR &= ~(INTRQ + IORDY);
CF_CONTROL_DIR |= DASP;
CF_DATA_DIR = 0;
CF_ADDR_OUT |= RST + WR + RD + CS1 + CS0;
CF_ADDR_OUT &=~(A2+A1+A0);
CF_CONTROL_OUT |= DASP;
}
/*********************************************************************************************************
** 函数名称: SYS_WaitInUS
** 功能描述: 延时等级约1微秒函数,该函数根据系统时间不同与不同,但不应少到1微秒。
** 输 入: times,延时时间等级
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void SYS_WaitInUS(uint32 times)
{
_NOP();
_NOP();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -