📄 ex15.c
字号:
/****************************************************************************/
//
//
// Created by Starlight Embeded Studio
// www.cedn.cn
// If there are any concerns on the code
// go to www.cedn.cn for discussion
//
/****************************************************************************/
#include <stdio.h>
#include "CfCard.h"
void Delay(int time)
{
static int DelayLoopCount = 500;
int i,j=0;
for(j=0;j<time;j++)
for(i=0;i<DelayLoopCount;i++);
}
void SetCfMode(CFMODE *CfMode, unsigned int Reg, unsigned int Mode, unsigned int Width)
{
//
// 0 for Reg=0
// 1 for Reg=1
//
CfMode->Reg = Reg; // 0 & 1
//
// 0 for IO Mode
// 1 for MEM Mode
//
CfMode->Mode = Mode; // 0 & 1
//
// W16 for 16 bit width
// WD8 for 8 bit mode
// WU8 for 8 bit even mode
//
CfMode->Width = Width;
}
unsigned int GetAddrFromRegIndex(int RegIndex,CFMODE *CfMode)
{
unsigned int Offset;
Offset = CPLD_BASE;
switch(CfMode->Width) {
case W16:
if (RegIndex & 1) RegIndex --;
break;
case WU8:
if (RegIndex & 1) RegIndex --;
Offset += CF_WIDTH_U8;
break;
case WD8:
Offset += CF_WIDTH_D8;
if (RegIndex & 1) {
Offset += CF_ODD_OFFSET;
RegIndex --;
}
break;
default:
break;
}
if (CfMode->Reg) Offset += CF_REG_OFFSET;
if (CfMode->Mode) Offset += CF_MEM_OFFSET;
return Offset + RegIndex;
}
unsigned char CFReadByte (int RegIndex, CFMODE *CfMode)
{
return *(volatile unsigned char *)GetAddrFromRegIndex( RegIndex, CfMode);
}
void CFWriteByte(int RegIndex,unsigned char Value, CFMODE *CfMode)
{
*(volatile unsigned char *)GetAddrFromRegIndex( RegIndex, CfMode ) = Value;
}
void CFReadMultiByte (int RegIndex,unsigned char *Buf, unsigned int Len, CFMODE *CfMode)
{
volatile unsigned char *p;
unsigned char *Buffer;
Buffer = Buf;
p = (volatile unsigned char *)GetAddrFromRegIndex( RegIndex, CfMode );
while (Len--) {
*Buffer++ = *p;
}
return;
}
void CFWriteMultiByte (int RegIndex,unsigned char *Buf, unsigned int Len, CFMODE *CfMode)
{
volatile unsigned char *p;
unsigned char *Buffer;
Buffer = Buf;
CfMode->Width = WD8;
p = (volatile unsigned char *)GetAddrFromRegIndex( RegIndex, CfMode );
while (Len--) {
*p = *Buffer++;
}
return;
}
unsigned short CFReadWord (int RegIndex, CFMODE *CfMode)
{
return *(volatile unsigned short *)GetAddrFromRegIndex( RegIndex, CfMode);
}
void CFWriteWord(int RegIndex,unsigned short Value, CFMODE *CfMode)
{
*(volatile unsigned short *)GetAddrFromRegIndex( RegIndex, CfMode ) = Value;
}
void CFReadMultiWord (int RegIndex,unsigned short *Buf, unsigned int Len, CFMODE *CfMode)
{
volatile unsigned short *p;
unsigned short *Buffer;
int Width;
Buffer = Buf;
Width = CfMode->Width;
CfMode->Width = W16;
p = (volatile unsigned short *)GetAddrFromRegIndex( RegIndex, CfMode);
CfMode->Width = Width;
while (Len--) {
*Buffer++ = *p;
}
return;
}
void CFWriteMultiWord (int RegIndex,unsigned short *Buf, unsigned int Len, CFMODE *CfMode)
{
volatile unsigned short *p;
unsigned short *Buffer;
int Width;
Buffer = Buf;
Width = CfMode->Width;
CfMode->Width = W16;
p = (volatile unsigned short *)GetAddrFromRegIndex( RegIndex, CfMode);
CfMode->Width = Width;
while (Len--) {
*p = *Buffer++;
}
return;
}
DISKINFO DiskInfo;
unsigned char SecBuf[512];
int CFWaitBusy(CFMODE *CfMode)
{
unsigned short i = 0;
do {
if ((CFReadByte(CB_STAT,CfMode) & 0x80) != 0x80)
{
return 1;
}
i++;
} while (i != 0);
return 0;
}
int CFWaitData(CFMODE *CfMode)
{
unsigned short i = 0;
do {
if ((CFReadByte(CB_STAT,CfMode) & 0xD8) == 0x58)
{
return 1;
}
i++;
} while (i != 0);
return 0;
}
int CFReadData(unsigned short * Buf, unsigned int Len, CFMODE *CfMode)
{
if (!CFWaitData(CfMode)) return 0;
CFReadMultiWord(CB_DATA, Buf, Len>>1, CfMode);
return 1;
}
int CFWriteData(unsigned short * Buf, unsigned int Len, CFMODE *CfMode)
{
if (!CFWaitData(CfMode)) return 0;
CFWriteMultiWord(CB_DATA, Buf, Len>>1, CfMode);
return 1;
}
int CFWriteCmd(PARAM * Params, CFMODE *CfMode)
{
if (!CFWaitBusy(CfMode)) return 0;
CFWriteByte(CB_FR, Params->Feature, CfMode);
CFWriteByte(CB_SC, Params->SectorCount, CfMode);
CFWriteByte(CB_SN, Params->SectorNumber, CfMode);
CFWriteByte(CB_CL, Params->Cylinder & 0xFF, CfMode);
CFWriteByte(CB_CH, (Params->Cylinder >> 8) & 0xFF, CfMode);
CFWriteByte(CB_DH, Params->DriveHead, CfMode);
if (!CFWaitBusy(CfMode)) return 0;
CFWriteByte(CB_CMD, Params->Command, CfMode);
return 1;
}
int CFCmdBlock(PARAM *Param,CFMODE *CfMode)
{
if (!CFWriteCmd(Param, CfMode)) return 0;
if (!CFReadData((unsigned short *)SecBuf,IDE_SECTOR_SIZE, CfMode)) return 0;
if (CFReadByte(CB_STAT,CfMode)!=0x50) return 0;
return 1;
}
int CFGetInfo(CFMODE *CfMode)
{
PARAM Param;
unsigned short *InfoBuf;
DiskInfo.NumHeads = 0u;
DiskInfo.NumCylinders = 0u;
DiskInfo.NumSectorsPerTrack = 0u;
DiskInfo.NumSectors = 0ul;
DiskInfo.AddressMode = IDE_DH_CHS;
DiskInfo.DriveExists = 0;
memset(&Param,sizeof(PARAM),0);
Param.DriveHead = IDE_DH_DEFAULT;
Param.Command = 0xec; //CMD_IDENTIFY_DEVICE;
if (!CFWriteCmd(&Param, CfMode)) return 0;
if (!CFReadData((unsigned short *)SecBuf,IDE_SECTOR_SIZE, CfMode)) return 0;
if (CFReadByte(CB_STAT,CfMode)!=0x50) return 0;
InfoBuf = (unsigned short *)SecBuf;
DiskInfo.NumHeads = InfoBuf[3];
DiskInfo.NumCylinders = InfoBuf[1];
DiskInfo.NumSectorsPerTrack = InfoBuf[6];
DiskInfo.NumSectors = *((unsigned int*)&(InfoBuf[60]));
DiskInfo.AddressMode = IDE_DH_CHS;
DiskInfo.DriveExists = 1;
printf( "CF IDE0: SECTORS=[%d], HEADS=[%d], CYLINDERS=[%d]\n",
DiskInfo.NumSectorsPerTrack,
DiskInfo.NumHeads,
DiskInfo.NumCylinders);
if (InfoBuf[49] & 0x200) { /* bit 9 of capability word is lba supported bit */
DiskInfo.AddressMode = IDE_DH_LBA;
printf("IDE MODE: IDE_DH_LBA\n");
} else {
DiskInfo.AddressMode = IDE_DH_CHS;
printf("IDE Mode: IDE_DH_CHS\n");
}
return 1;
}
void CFPowerOn(int n)
{
if (n) *CPLD_REG1 |= 0x10;
else *CPLD_REG1 &= 0xEF;
}
int CFGetPower(void)
{
if (*CPLD_REG1 & 0x10) return 1;
else return 0;
}
int CFGetCard(void)
{
if (*CPLD_REG5 & 0x40) return 0;
else return 1;
}
void CFSetIDE(int n)
{
if (n) *CPLD_REG2 |= 0x04;
else *CPLD_REG2 &= 0xFB;
}
void CFReset(void)
{
*CPLD_REG1 |= 0x80;
Delay(5);
*CPLD_REG1 &= 0x7F;
Delay(5);
}
int CFInit(CFMODE *CfMode)
{
CFReset();
SetCfMode(CfMode, 0, 1, WD8);
/*
** set memory access mode
*/
CFWriteByte( 0x200, 0x80, CfMode);
Delay(10);
/*
** set memory access mode
*/
CFWriteByte( 0x200, 0x00, CfMode);
SetCfMode(CfMode, 1, 1, WD8);
CFWriteByte(CB_CMD, CMD_IDLE_IMMEDIATE1, CfMode);
CFWaitBusy(CfMode);
return 1;
}
int CFInitIDE(CFMODE *CfMode)
{
SetCfMode(CfMode, 0, 0, WD8);
CFWriteByte(CB_CMD, CMD_IDLE_IMMEDIATE1, CfMode);
CFWaitBusy(CfMode);
return 1;
}
int CFDetect(CFMODE *CfMode)
{
unsigned char sc;
unsigned char sn;
/*
** set up Device Control register
*/
CFWriteByte( CB_DC, CB_DC_HD15 | (CB_DC_NIEN ), CfMode);
/*
** lets see if there is a device 0
*/
CFWriteByte( CB_DH, CB_DH_DEV0, CfMode);
Delay(2);
CFWriteByte( CB_SC, 0x55,CfMode );
CFWriteByte( CB_SN, 0xaa,CfMode );
CFWriteByte( CB_SC, 0xaa,CfMode );
CFWriteByte( CB_SN, 0x55,CfMode );
CFWriteByte( CB_SC, 0x55,CfMode );
CFWriteByte( CB_SN, 0xaa,CfMode );
sc = CFReadByte( CB_SC ,CfMode);
sn = CFReadByte( CB_SN ,CfMode);
if ( ( sc == 0x55 ) && ( sn == 0xaa ) ) return 1;
return 0;
}
void OutHex(unsigned char *Buf)
{
int i;
printf("\n%04X: ",0); for (i=0;i<512;i++) {
printf("%02X ",Buf[i]);
if ((i&0x0F) == 0x0F && i!=0x1FF) printf("\n%04X: ",i+1);
}
}
void SetLbaParam(unsigned int Lba,unsigned int Count, PARAM *Params)
{
Params->Feature = 0;
Params->SectorCount = Count;
Params->SectorNumber = (unsigned char)Lba;
Params->Cylinder = (unsigned short)(Lba>>8);
Params->DriveHead = 0xE0|((Lba>>24)&0x0F);
}
int Test15()
{
CFMODE CFMode;
PARAM Params;
int quit;
printf("Start CF Card Test!\n");
quit = 0;
CFSetIDE(0);
CFPowerOn(0);
Delay(200);
CFPowerOn(1);
Delay(200);
CFReset();
CFInit(&CFMode);
if (!CFDetect(&CFMode)) {
printf("No CF Card is detected!\n");
quit = 1;
}
if (!quit) {
printf("\nOK! CF is detected!\n");
if (!CFGetInfo(&CFMode)) {
return 0;
}
SetLbaParam(0,1,&Params);
Params.Command = CMD_READ_SECTORS;
if (CFCmdBlock(&Params,&CFMode)) {
printf("Sector 0 on Drive:\n");
OutHex(SecBuf);
} else {
printf("Identify Drive Information:\n");
OutHex(SecBuf);
}
}
CFPowerOn(0);
printf("\nFinish CF Card Test!\n");
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -