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

📄 cf.c

📁 Build ourself a MP3 Player
💻 C
字号:
#include "cf.h"
// Compact flash state
int32 CF_CurrSector; // the sector we're currently reading/writing
int16 CF_CurrByteInSector;  // what byte in that sector we're at
boolean  CF_isValid; // CF seems ok

boolean is_CF_Out() {
   input(CF_CD);             // check if the CD line is high
}



void CF_SetAddr(byte addr) {
   output_bit(CF_A0, bit_test(addr, 0));
   output_bit(CF_A1, bit_test(addr, 1));
   output_bit(CF_A2, bit_test(addr, 2));
}

// write data to CF port addr
void CF_TaskFileWrite(byte addr, byte data)
{
   cf_SetAddr(addr);
   cf_WriteByte(data);
}

// read byte from CF port addr
byte CF_TaskFileRead(byte addr)
{
   CF_SetAddr(addr);
   return(CF_ReadByte());
}

boolean CF_isBusy(void) {
  return ((CF_TaskFileRead(7) & 0x80) == 0x80);
}

boolean CF_isReady(void) {
  return ((CF_TaskFileRead(7) & 0x40) == 0x40);
}

/********************/
// reset the card via the RST line

void CF_ResetCard(void) {
  output_high(CF_RESET);
  delay_ms(255);
  output_low(CF_RESET);
  delay_ms(10);
}

void CF_Disable(void) {
   // default CF power down signals
   output_low(CF_OE);
   output_low(CF_WE);
   output_high(CF_CE);
   CF_SetAddr(0);
   output_high(CF_RESET);
   // presumption of invalidity
   CF_isValid=false;
}

byte CF_Enable(void) {
   CF_Disable();
   output_low(CF_CE);
   printf("Resetting Card.. ");
   CF_ResetCard();
   if (is_CF_Out()) {
      CF_isValid = false;
      printf("No CF found!\n\r");
      return NO_CF;
     }
   output_high(CF_OE);
   output_high(CF_WE);
   set_tris_d(TRIS_D_INPUT);
   CF_isValid = true;
   return CF_OK;
}

/*********************/

void CF_Identify(void) {
   byte c;

   if (!CF_isValid)
      return;

   output_low(CF_CE);
   printf("Identifying CF.. ");
   while (CF_isBusy() && (!CF_isReady())) {
      delay_us(1);
      //putc('.');
   }

//   printf("set drive ");
   CF_taskFileWrite(6, 0xA0);   // drive 0
//   printf("command id ");
   CF_taskFileWrite(REG_COMMAND, COMMAND_IDENTIFY);   // identify drive command

   while ((CF_ReadByte()&0x80)==0x80);  // wait for ready

   CF_setAddr(0);

   for(c = 0; c < 0xFF; c++) {
      putc(cf_ReadByte());
   }
   for(c = 0; c < 0xFF; c++) {
      putc(cf_ReadByte());
   }
   putc(cf_readByte());
   putc(cf_readByte());
}

/********************************************/
// write 1 byte into current CF port
void CF_WriteByte(byte data)
{
   waitforready();
   // set data
   set_tris_d(TRIS_D_OUTPUT);
   output_d(data);
   // Strobe write signal
   output_low(CF_WE);
   nop;
   output_high(CF_WE);
   set_tris_d(TRIS_D_INPUT);
}

// read 1 byte from current CF port
byte CF_ReadByte()
{
   byte data;
   waitforready();
   set_tris_d(TRIS_D_INPUT);
   // strobe read signal and get data
   waitforready();
   output_low(CF_OE);
   data = input_d();
   output_high(CF_OE);
   //	printf("read 0x%x ", data);
   return data;
}

void CF_WriteInt16(int16 data) {
   CF_WriteByte(data >> 8);
   CF_WriteByte(data & 0xff);
}

int16 CF_ReadInt16(void) {
   byte lo;
   int16 ret;

   lo = CF_ReadByte();
   ret = CF_ReadByte();
   ret <<= 8;
   ret |= lo;
   return ret;
}

void CF_WriteInt32(int32 data) {
   CF_WriteByte(data >> 24);
   CF_WriteByte(data >> 16);
   CF_WriteByte(data >> 8);
   CF_WriteByte(data);
}

int32 CF_ReadInt32(void) {
   int16 lo;
   int32 ret;
   lo = CF_ReadInt16();
   ret = CF_ReadInt16();
   ret <<= 16;
   ret |= lo;
   return ret;
}

// skip bytes from current sector buffer
void CF_ReadSkipBytes(int count)
{
   //	printf("skipping %d bytes\n\r", count);
   set_tris_d(TRIS_D_INPUT);
   while (count > 0) {
      waitforready();
      output_low(CF_OE);
      nop;
      output_high(CF_OE);
      count--;
   }
}

void CF_ReadSkipInt16(byte count)
{
   CF_ReadSkipBytes(count);
   CF_ReadSkipBytes(count);
}

/************************************************/
// begin writing or reading the CF_CurrSector

void CF_StartSectorRead() {      // uses CF_CurrSector
   while (CF_isBusy() && (!CF_isReady())) {delay_us(1);}

   //printf("Beginning read from sector 0x%8LX\n\r", CF_CurrSector);
   CF_TaskFileWrite(REG_SECTORCOUNT, 1);
   CF_TaskFileWrite(REG_SECTORNUM, CF_CurrSector);
   CF_TaskFileWrite(REG_CYLINDERLOW, CF_CurrSector >> 8);
   CF_TaskFileWrite(REG_CYLINDERHIGH, CF_CurrSector >> 16);
   CF_TaskFileWrite(REG_HEAD, 0xE0 | ((CF_CurrSector >> 24) & 0x0F));
   CF_TaskFileWrite(REG_COMMAND, COMMAND_READSECTOR);

   while ((CF_ReadByte()&0x88)!=0x08);      // check if valid??

   CF_SetAddr(0);
}

void CF_StartSectorWrite() {      // uses CF_CurrSector
   while (CF_isBusy() && (!CF_isReady())) {putc('.'); delay_us(1);}

   //printf("Beginning write to sector 0x%8LX\n\r", CF_CurrSector);
   CF_TaskFileWrite(REG_SECTORCOUNT, 1);
   CF_TaskFileWrite(REG_SECTORNUM, CF_CurrSector);
   CF_TaskFileWrite(REG_CYLINDERLOW, CF_CurrSector >> 8);
   CF_TaskFileWrite(REG_CYLINDERHIGH,  CF_CurrSector >> 16);
   CF_TaskFileWrite(REG_HEAD, 0xE0 | (( CF_CurrSector >> 24) & 0x0F));
   CF_TaskFileWrite(REG_COMMAND, COMMAND_WRITESECTOR);
   delay_ms(1);
   while ((CF_ReadByte()&0x88)!=0x08);     // check if valid??

   CF_SetAddr(0);
}

/***************************************/
// dump the contents of sectorbuff into a sector or vice versa
// assumes you've StartSectorWrite/Read 'd

void CF_ReadSectorIntoBuff() {
   int16 i;
   for (i=0; i < (int16)512; i++) {
      sectorbuff[i] = CF_ReadByte();
   }
}

void CF_WriteBuffIntoSector() {
   int16 i;
   for (i=0; i < (int16)512; i++) {
      CF_WriteByte(sectorbuff[i]);
      //putc('.');
   }
}

/***************************************/
void CF_DumpSector() {      // uses CF_CurrSector
   int16 i;

   CF_StartSectorRead();

   CF_ReadSectorIntoBuff();
   for (i=0; i < (int16)512; i++) {
      putc(sectorbuff[i]);
   }
}

⌨️ 快捷键说明

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