⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compact.c

📁 使用IAR430编译源文件
💻 C
字号:
//###########################################################
// File: compact.c
//
// Read-/Writeroutines for CompactFlash in LBA mode.
// CHS mode not supported.

//#########################################################################

#include <io.h>

#include "dos.h"

#ifdef COMPACTFLASH_CARD

//######################################################
unsigned char CFReadSector(unsigned long lba, unsigned char *buf)
//######################################################
{
 unsigned int i;
 unsigned char by;
 unsigned char *p;

 if(lba>=maxsect) return 1; //sectornumber too big

 if(CFWaitReady()) return 1;
 
// CFWriteAdr(CF_FEATURES,0); //Brauch ich nicht
 CFWriteAdr(CF_SECCOUNT,1);   //einen Sektor lesen

 by=(unsigned char)lba;
 CFWriteAdr(CF_LBA0,by);            //D7..0
 by=(unsigned char)(lba>>8);
 CFWriteAdr(CF_LBA1,by);            //D15..8
 by=(unsigned char)(lba>>16);
 CFWriteAdr(CF_LBA2,by);            //D23..16
 by=(unsigned char)(lba>>24);
 by&=0x0F;              //Nur die vier unteren Bits g黮tig
 by|=0xE0;              //LBA-Mode Drive0
 CFWriteAdr(CF_LBA3,by);          //D27..24
 CFWriteAdr(CF_STACOM,CF_READ_SEC);

 if(CFWaitDrq()) return 2;

 p=buf;
 
 CF_DATA_DIR_IN();
 CFSetAdr(CF_IO);
 CF_CS_OFF();
 for(i=0; i<BYTE_PER_SEC; i++)
  {
   CF_RD_OFF();
   NOP(); 
   NOP(); 
        
   NOP();

#ifdef F_16 //16MHz processor clock
   NOP();
#endif
   
   *p++=CF_READ_DATA();
   CF_RD_ON();
  } 

 CF_CS_ON();

 return 0;
}

#ifdef DOS_WRITE
//######################################################
unsigned char CFWriteSector(unsigned long lba, unsigned char *buf)
//######################################################
{
 unsigned int i;
 unsigned char by;
 unsigned char *p;

 if(lba>=maxsect) return 1; //sectornumber too big
 if(CFWaitReady()) return 1;
 
// CFWriteAdr(CF_FEATURES,0); //Brauch ich nicht
 CFWriteAdr(CF_SECCOUNT,1);   //einen Sektor schreiben

 by=(unsigned char)lba;
 CFWriteAdr(CF_LBA0,by);            //D7..0
 by=(unsigned char)(lba>>8);
 CFWriteAdr(CF_LBA1,by);            //D15..8
 by=(unsigned char)(lba>>16);
 CFWriteAdr(CF_LBA2,by);            //D23..16
 by=(unsigned char)(lba>>24);
 by&=0x0F;              //Nur die vier unteren Bits g黮tig
 by|=0xE0;              //LBA-Mode Drive0
 CFWriteAdr(CF_LBA3,by);          //D27..24
 CFWriteAdr(CF_STACOM,CF_WRITE_SEC);

 if(CFWaitDrq()) return 2;

 p=buf; //using a pointer is much faster than indexing buf[i]

 CFSetAdr(CF_IO);
 CF_DATA_DIR_OUT();
 CF_CS_OFF();

 for(i=0; i<BYTE_PER_SEC; i++)
  {
//   CF_WRITE_DATA(buf[i]);
   CF_WRITE_DATA(*p++);
#ifdef F_16 //16MHz processor clock
   NOP();
#endif
   CF_WR_OFF();
   NOP();
#ifdef F_16 //16MHz processor clock
   NOP();
#endif
   
   CF_WR_ON();
   NOP();
#ifdef F_16 //16MHz processor clock
   NOP();
#endif
  }

 CF_CS_ON();

 CF_DATA_DIR_IN();
 return 0;
}
#endif //DOS_WRITE

//######################################################
unsigned char CFIdentify(void)
//######################################################
{
// unsigned long maxtracks;
// unsigned int heads,sectors_per_track;
 unsigned int i;
 union Convert *cv;

 if(CFWaitReady()) return 1;
 
// cf_features=0; //Brauch ich nicht
// cf_seccount=1;   //einen Sektor lesen
// cf_lba0=1;       //LBA ist hier eigentlich egal, also 1
// cf_lba1=0;
// cf_lba2=0;
// cf_lba3=0xE0;
 CFWriteAdr(CF_STACOM,CF_IDENTIFY);

 if(CFWaitDrq()) return 2;
  
 for(i=0; i<BYTE_PER_SEC; i++) dirbuf[i]=CFReadAdr(CF_IO);
 
// cv=(union Convert *)&dirbuf[2];
// maxtracks=cv->ul;          //Anzahl Tracks

// cv=(union Convert *)&dirbuf[6];
// heads=cv->ui;              //Anzahl Heads

// cv=(union Convert *)&dirbuf[12];
// sectors_per_track=cv->ui; //Sectors per Track

// this is the only information we need 
 cv=(union Convert *)&dirbuf[14];
 maxsect=(unsigned long)cv->ui << 16;         // number of sectors
 cv=(union Convert *)&dirbuf[16];
 maxsect+=cv->ui;

 return 0;
}

//######################################################
unsigned char CFWaitReady(void)
//######################################################
{
 unsigned char by;

 by=CFReadAdr(CF_STACOM);
 if(by & 0x01) return 1; //Fehler !

 do
  {
   by=CFReadAdr(CF_STACOM);
   by&=0xF0;
   
  }while(by!=0x50); //Endlosschleife m鰃lich !
  
 return 0; 
}

//######################################################
unsigned char CFWaitDrq(void)
//######################################################
{
 unsigned char by;

 by=CFReadAdr(CF_STACOM);
 if(by & 0x01) return 1; //Fehler !

 do
  {
   by=CFReadAdr(CF_STACOM);
   by&=0xF8;
   
  }while(by!=0x58); //Endlosschleife m鰃lich !
  
 return 0; 
}

//######################################################
unsigned char CFReadAdr(unsigned char adr)
//######################################################
{
 unsigned char by;
 
 CF_DATA_DIR_IN();
 CFSetAdr(adr);
 CF_CS_OFF();
 CF_RD_OFF();
 NOP(); //Schon bei 8MHz mu?man hier etwas warten
 NOP(); //Es k鰊nte evtl. n鰐ig sein hier noch mehr
        //nop einzuf黦en, um m鰃lichst viele CF zu lesen
        //Bei mir reichten bisher 2 nop
        //Sicherheitshalber noch einen mehr
 NOP();
        //Sonst meldet CFWaitReady() immer Fehler

#ifdef F_16 //16MHz processor clock
   NOP();
#endif
   
 by=CF_READ_DATA();
 CF_RD_ON();
 CF_CS_ON();
 return by;
}

//######################################################
unsigned char CFRead(void)
//######################################################
{
 unsigned char by;
 
 CF_RD_OFF();
 NOP(); //Schon bei 8MHz mu?man hier etwas warten
 NOP(); //Es k鰊nte evtl. n鰐ig sein hier noch mehr
        //nop einzuf黦en, um m鰃lichst viele CF zu lesen
        //Bei mir reichten bisher 2 nop
        //Sicherheitshalber noch einen mehr
 NOP();

#ifdef F_16 //16MHz processor clock
   NOP();
#endif

 by=CF_READ_DATA();
 CF_RD_ON();
 return by;
}

//######################################################
void CFWriteAdr(unsigned char adr, unsigned char dat)
//######################################################
{
 CF_DATA_DIR_OUT();
 CFSetAdr(adr);
 CF_WRITE_DATA(dat);
 NOP();
#ifdef F_16 //16MHz processor clock
   NOP();
#endif

 CF_CS_OFF();
 NOP();
#ifdef F_16 //16MHz processor clock
   NOP();
#endif
 CF_WR_OFF();
 NOP();
#ifdef F_16 //16MHz processor clock
   NOP();
#endif
 CF_WR_ON();
 CF_CS_ON();
}

//######################################################
//Ist so kurz das man statt der Routine auch direkt oben
//per Macro einf黦en k鰊nte. Wird dann etwas schneller.
void CFSetAdr(unsigned char adr)
//######################################################
{
 unsigned char by;

 by=CF_ADR_PIN;  //Portpins lesen
 by&=0xF0;       //D0..D3 l鰏chen
 by|=adr;        //adr reinodern
 CF_ADR_PORT=by; //und ausgeben
}

#endif //COMPACTFLASH_CARD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -