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

📄 lowlvl.c

📁 CF卡读卡程序
💻 C
📖 第 1 页 / 共 5 页
字号:
* RETURNS:
*      ERR_NONE
*      ERR_WRITE
****************************************************************************/
WORD SRAMWrite(DWORD CardAddress, DWORD Length, BYTE_PTR Buffer)
{
   FULL_WORD_PTR volatile pointer;

   PositionPtr(pointer, CardAddress);

   /* Just push the data out. "_f" is for a far copy */
   fmemoryCopy(pointer, Buffer, Length);

   return(ERR_NONE);
}
#endif

/****************************************************************************
* SRAMROMRead
*
* FUNCTION:
*      Read bytes from SRAM.
*
* FORMAT:
*      int SRAMROMRead(CardAddress, Length, BufferAddress)
*
* INPUTS:
*      dword   CardAddress     - address on card to begin read
*      int     Length          - number of bytes to read
*      dword   BufferAddress   - address in system RAM to read into
*
* GLOBALS:
*      None
*
* CALLS:
*      _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
*      ERR_NONE
*      ERR_WRITE
****************************************************************************/
WORD SRAMROMRead(DWORD CardAddress, DWORD Length, BYTE_PTR Buffer)
{
   FULL_WORD_PTR volatile pointer;

   PositionPtr(pointer, CardAddress);

   /* Just suck the data out. "_f" is for a far copy */
   fmemoryCopy(Buffer, pointer, Length);

   return(ERR_NONE);
}


/*
  The CFI query command must be issued to address 55h on the
  CFI component.
*/
#define Address55h 0x55

/*
  CFI command set codes and other values.
*/
#define CmdSetSCS      0x0001
#define CmdSeti8Mb     0x0003
#define EraseSuspend   0x02
#define SuspendToWrite 0x01
/* 09/07/97 KES change 0x20 -> 0x10 */
#define EraseQueueFlag 0x10

#if CFI_OPTIONAL
#define ChipEraseFlag         0x01
#define ProgramSuspendFlag    0x04
#define LockUnlockFlag        0x08
#define QueuedEraseFlag       0x10
#define BlockLockStatusFlag   0x01
#define BlockValidStatusFlag  0x02
#endif
#define EraseSuspendFlag      0x02


/*
  Believe it or not, it is easier to get everything in with BYTES in the
  structures, then pull out the ones you want then trying to swap things
  depending on what endianness the system is.  These defines put out the
  size they are told to, from the BYTE array passed in.
  This method removes any worries about byte order on the system the program
  is running on.
  Also, this method allows for uniform C code for both x8 and x8x16 arrays
  that otherwise would have to have two virtually identical (and very large)
  code segments that did all the calculations for each. Instead, this
  macro calculates both at runtime and at compiletime certain parameters
  and pulls in the appropriate bytes.
  Provides for more readable code, and reduces code size.
  It is completely ANSI C compatible.
*/

#define BYTEOUT(bob) ((!CFIStruct) ? \
   (BYTE)((sizeof(CFIx8paired->bob) == 2) ? \
      CFIx8paired->bob[0] : \
      CFIx8paired->bob[0]) : \
   (BYTE)((sizeof(CFIx8x16paired->bob) == 2) ? \
      CFIx8x16paired->bob[0] : \
      CFIx8x16paired->bob[0]))

#define WORDOUT(bob) ((!CFIStruct) ? \
   (WORD)((sizeof(CFIx8paired->bob) == 4) ? \
      (((WORD)CFIx8paired->bob[2] << 8) | CFIx8paired->bob[0]) : \
      (((WORD)CFIx8paired->bob[1] << 8) | CFIx8paired->bob[0])) : \
   (WORD)((sizeof(CFIx8x16paired->bob) == 4) ? \
      (((WORD)CFIx8x16paired->bob[2] << 8) | CFIx8x16paired->bob[0]) : \
      (((WORD)CFIx8x16paired->bob[4] << 8) | CFIx8x16paired->bob[0])))

#define DWORDOUT(bob) ((!CFIStruct) ? \
   (DWORD)((sizeof(CFIx8paired->bob) == 8) ? \
      (((DWORD)CFIx8paired->bob[6] << 24) | ((DWORD)CFIx8paired->bob[4] << 16) | \
         ((DWORD)CFIx8paired->bob[2] << 8) | CFIx8paired->bob[0]) : \
      (((DWORD)CFIx8paired->bob[3] << 24) | ((DWORD)CFIx8paired->bob[2] << 16) | \
         ((DWORD)CFIx8paired->bob[1] << 8) | CFIx8paired->bob[0])) : \
   (DWORD)((sizeof(CFIx8x16paired->bob) == 8) ? \
      (((DWORD)CFIx8x16paired->bob[6] << 24) | ((DWORD)CFIx8x16paired->bob[4] << 16) | \
         ((DWORD)CFIx8x16paired->bob[2] << 8) | CFIx8x16paired->bob[0]) : \
      (((DWORD)CFIx8x16paired->bob[12] << 24) | ((DWORD)CFIx8x16paired->bob[8] << 16) | \
         ((DWORD)CFIx8x16paired->bob[4] << 8) | CFIx8x16paired->bob[0])))


/****************************************************************************
* QueryCFI                                                    Ver69
*
* FUNCTION:
*      Determine if flash is CFI-compliant; parse data if so
*
* FORMAT:
*      int QueryCFI(void)
*
* INPUTS:
*      es:[0] -> flash mapped at address 0
*      si -> FTLTable
*
* GLOBALS:
*      FlashRead
*      FlashWrite
*      FlashErase
*      FlashStatus
*      FlashSuspend
*      FlashResume
*
* CALLS:
*      _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
*      ERR_NONE  (0000h)
*      ERR_JEDEC (0013h)
*      ERR_PARAM (0003h)
****************************************************************************/
WORD QueryCFI(MEDIA_INFO *temp_Info)
{
/*
  This is the CFI query structure which the device will present
  in response to the CFI query command.  The second portion is
  the vendor-specific region, as defined by Intel for both SCS
  chips (like MLC) and standard 8Mb-compatible CFI chips.  Also,
  this particular version appears when the media is implemented
  as paired x8-only chips or a single x16 chips.  In each 16-bit
  piece of data, the meaningful data will be duplicated in the
  upper and lower 8 bits.
*/
typedef struct
{
   BYTE  Reserved[0x20];                     /* offset 00h */
   WORD  SignatureQ;                         /* offset 20h */
   WORD  SignatureR;                         /* offset 22h */
   WORD  SignatureY;                         /* offset 24h */
   BYTE  CmdSet[4];                          /* offset 26h */
   BYTE  CmdSetAddr[4];                      /* offset 2Ah */
   BYTE  AltCmdSet[4];                       /* offset 2Eh */
   BYTE  AltCmdSetAddr[4];                   /* offset 32h */
   BYTE  MinVcc[2];                          /* offset 36h */
   BYTE  MaxVcc[2];                          /* offset 38h */
   BYTE  MinVpp[2];                          /* offset 3Ah */
   BYTE  MaxVpp[2];                          /* offset 3Ch */
   BYTE  typBytePgmTime[2];                  /* offset 3Eh */
   BYTE  typBufferPgmTime[2];              /* offset 40h */
   BYTE  typBlockEraseTime[2];               /* offset 42h */
   BYTE  typChipEraseTime[2];                /* offset 44h */
   BYTE  maxBytePgmTime[2];                  /* offset 46h */
   BYTE  maxBufferPgmTime[2];              /* offset 48h */
   BYTE  maxBlockEraseTime[2];               /* offset 4Ah */
   BYTE  maxChipEraseTime[2];                /* offset 4Ch */
   BYTE  DeviceSize[2];                      /* offset 4Eh */
   BYTE  Interface[4];                       /* offset 50h */
   BYTE  WriteSize[4];                       /* offset 54h */
   BYTE  BlkRegions[2];                      /* offset 58h */
#if !CFI_ERASE_REGIONS
   BYTE  BlksRegion[8];                      /* offset 5Ah */
#else
   BYTE BlksRegion[MAX_ERASE_REGIONS][8];
#endif
} CFIx8PAIRED_STRUCT;

typedef struct
{
   BYTE Signature[6];                        /* offset 00h */
   BYTE Version[4];                          /* offset 06h */
   BYTE Features[2];                         /* offset 0Ah */
   BYTE Reserved[6];                         /* offset 0Ch */
   BYTE Suspend[2];                          /* offset 12h */
   BYTE Status[4];                           /* offset 14h */
   BYTE OptVcc[2];                           /* offset 18h */
   BYTE OptVpp[2];                           /* offset 1Ah */
} VSx8PAIRED_STRUCT;

/*
  This particular CFI/SCS structure pair represents x8/x16 chips
  in a paired x8 implementation.  In each 32-bit piece of data,
  the meaningful information will be duplicated in each of the
  four 8-bit pieces.
*/
typedef struct
{
   BYTE  Reserved[0x40];                        /* offset 00h */
   WORD  SignatureQ[2];                         /* offset 40h */
   WORD  SignatureR[2];                         /* offset 44h */
   WORD  SignatureY[2];                         /* offset 48h */
   BYTE  CmdSet[8];                             /* offset 4Ch */
   BYTE  CmdSetAddr[8];                         /* offset 54h */
   BYTE  AltCmdSet[8];                          /* offset 5C*/
   BYTE  AltCmdSetAddr[8];                      /* offset 64h */
   BYTE  MinVcc[4];                             /* offset 6Ch */
   BYTE  MaxVcc[4];                             /* offset 70h */
   BYTE  MinVpp[4];                             /* offset 74h */
   BYTE  MaxVpp[4];                             /* offset 78h */
   BYTE  typBytePgmTime[4];                     /* offset 7Ch */
   BYTE  typBufferPgmTime[4];                 /* offset 80h */
   BYTE  typBlockEraseTime[4];                  /* offset 84h */
   BYTE  typChipEraseTime[4];                   /* offset 88h */
   BYTE  maxBytePgmTime[4];                     /* offset 8Ch */
   BYTE  maxBufferPgmTime[4];                 /* offset 90h */
   BYTE  maxBlockEraseTime[4];                  /* offset 94h */
   BYTE  maxChipEraseTime[4];                   /* offset 98h */
   BYTE  DeviceSize[4];                         /* offset 9Ch */
   BYTE  Interface[8];                          /* offset A0h */
   BYTE  WriteSize[8];                          /* offset A8h */
   BYTE  BlkRegions[4];                         /* offset B0h */
#if !CFI_ERASE_REGIONS
   BYTE  BlksRegion[16];                      /* offset 5Ah */
#else
   BYTE BlksRegion[MAX_ERASE_REGIONS][16];
#endif
} CFIx8x16PAIRED_STRUCT;

typedef struct
{
   BYTE Signature[12];                          /* offset 00h */
   BYTE Version[8];                             /* offset 0Ch */
   BYTE Features[4];                            /* offset 14h */
   BYTE Reserved[12];                           /* offset 18h */
   BYTE Suspend[4];                             /* offset 24h */
   BYTE Status[8];                              /* offset 28h */
   BYTE OptVcc[4];                              /* offset 30h */
   BYTE OptVpp[4];                              /* offset 34h */
} VSx8x16PAIRED_STRUCT;

   CFIx8PAIRED_STRUCT volatile      FAR_PTR CFIx8paired;
   VSx8PAIRED_STRUCT  volatile      FAR_PTR VSx8paired;
   CFIx8x16PAIRED_STRUCT volatile   FAR_PTR CFIx8x16paired;
   VSx8x16PAIRED_STRUCT  volatile   FAR_PTR VSx8x16paired;
   FULL_WORD_PTR volatile pointer0ed, pointer;
   WORD CmdSet = 0;
   WORD CommandSetAddr = 0;
   BYTE CFIStruct = 0;

#if CFI_ERASE_REGIONS
   BYTE CFIRegion;
#endif

   HWImplement = 0;

   PositionPtr(pointer0ed, temp_Info->media_size);
   pointer = pointer0ed;
   IncreasePtr(pointer, (Address55h * 2));

   *pointer = FlashCommandQueryCFI*0x101;   /* Issue QueryCFI command */

   CFIx8paired = (CFIx8PAIRED_STRUCT FAR_PTR)pointer0ed;                /* Set up struct pointer */

/* Set the CmdSet var */

   /* In this case, the setup of the chips returns doubles of the info,
      so they must be paired 8bit parts */
   if ((CFIx8paired->SignatureQ == (WORD)LETTERS_QQ) &&
       (CFIx8paired->SignatureR == (WORD)LETTERS_RR) &&
       (CFIx8paired->SignatureY == (WORD)LETTERS_YY))
   {
      CmdSet = (CFIx8paired->CmdSet[3] << 8) + CFIx8paired->CmdSet[0];

      HWImplement |= Implementx8+ImplementPaired;
      CFIStruct = 0;
   }
   else
   {
      /* Position pointer to 154h */
      IncreasePtr(pointer, (Address55h * 2));

      /* In this case, the setup of the chips returns quads of the info,
      so they must be paired 8/16bit parts */
      *pointer = FlashCommandQueryCFI*0x101;
      CFIx8x16paired = (CFIx8x16PAIRED_STRUCT FAR_PTR)pointer0ed;

      if ((CFIx8x16paired->SignatureQ[0] == (WORD)LETTERS_QQ) &&
          (CFIx8x16paired->SignatureR[0] == (WORD)LETTERS_RR) &&
          (CFIx8x16paired->SignatureY[0] == (WORD)LETTERS_YY))
      {
         CmdSet = (CFIx8x16paired->CmdSet[5] << 8) + CFIx8x16paired->CmdSet[0];

         HWImplement |= Implementx8x16+ImplementPaired;
         CFIStruct= 1;
      }
      else
	  {
         /* Set pointer to AAh, which is where we write first */
         DecreasePtr(pointer, (Address55h * 2));

         /* In this case a since 16bit part is doing all the work */
         if ((CFIx8paired->SignatureQ == (WORD)LETTER_Q) &&
             (CFIx8paired->SignatureR == (WORD)LETTER_R) &&
             (CFIx8paired->SignatureY == (WORD)LETTER_Y))
         {
            CmdSet = (CFIx8paired->CmdSet[3] << 8) + CFIx8paired->CmdSet[0];

            HWImplement |= Implementx16;
            CFIStruct = 0;
         }
         else
         {
            *pointer0ed = FlashCommandClear*0x101;
            *pointer0ed = FlashCommandClear*0x101;
            return (ERR_JEDEC);
         }
      }
   }

   /* Here we scroll through the table trying to match the JEDEC_ID to
      something in it. */
   Offset=0;
   while(CFITable[Offset].CommandSetID != 0xFFFF)
   {
      if (CFITable[Offset].CommandSetID == CmdSet)
         break;

      Offset++;
   }

   if (CFITable[Offset].CommandSetID == 0xFFFF)
   {
      while((*pointer0ed = FlashCommandStatus*0x101), (*pointer0ed != 0x8080))
         *pointer0ed = FlashCommandClear*0x101;

      return (ERR_JEDEC);
   }

   /* Set up pointers for functions based on table values */
#if SEGMENTED
   *(WORD_PTR)&FlashRead    = (WORD)(CFITable[Offset].DeviceRead);
   *(WORD_PTR)&FlashWrite   = (WORD)(CFITable[Offset].DeviceWrite);
   *(WORD_PTR)&FlashErase   = (WORD)(CFITable[Offset].DeviceErase);
#if ERASE_BACKGROUND
   *(WORD_PTR)&FlashStatus  = (WORD)CFITable[Offset].DeviceStatus;
   *(WORD_PTR)&FlashSuspend = (WORD)CFITable[Offset].DeviceSuspend;
   *(WORD_PTR)&FlashResume  = (WORD)CFITable[Offset].DeviceResume;
#endif
#if CFI_OPTIONAL
   *(WORD_PTR)&FlashLock  = (WORD)CFITable[Offset].DeviceLock;
   *(WORD_PTR)&FlashUnlock  = (WORD)CFITable[Offset].DeviceUnlock;
   *(WORD_PTR)&FlashChipErase  = (WORD)CFITable[Offset].DeviceChipErase;
   *(WORD_PTR)&FlashConfigureStatus  = (WORD)CFITable[Offset].DeviceConfigureStatus;
#endif
#else
   *(DWORD_PTR)&FlashRead    = (DWORD)(CFITable[Offset].DeviceRead);
   *(DWORD_PTR)&FlashWrite   = (DWORD)(CFITable[Offset].DeviceWrite);
   *(DWORD_PTR)&FlashErase   = (DWORD)(CFITable[Offset].DeviceErase);
#if ERASE_BACKGROUND
   *(DWORD_PTR)&FlashStatus  = (DWORD)(CFITable[Offset].DeviceStatus);
   *(DWORD_PTR)&FlashSuspend = (DWORD)(CFITable[Offset].DeviceSuspend);
   *(DWORD_PTR)&FlashResume  = (DWORD)(CFITable[Offset].DeviceResume);
#endif
#if CFI_OPTIONAL

⌨️ 快捷键说明

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