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

📄 lowlvl.c

📁 CF卡读卡程序
💻 C
📖 第 1 页 / 共 5 页
字号:
   *(DWORD_PTR)&FlashLock  = (DWORD)CFITable[Offset].DeviceLock;
   *(DWORD_PTR)&FlashUnlock  = (DWORD)CFITable[Offset].DeviceUnlock;
   *(DWORD_PTR)&FlashChipErase  = (DWORD)CFITable[Offset].DeviceChipErase;
   *(DWORD_PTR)&FlashConfigureStatus  = (DWORD)CFITable[Offset].DeviceConfigureStatus;
#endif
#endif

#if CFI_ERASE_REGIONS
   temp_Info->number_regions = BYTEOUT(BlkRegions);
   for (CFIRegion = 0; CFIRegion < temp_Info->number_regions; CFIRegion++)
   {
	 /* Find block size and set in MEDIA_INFO ptr */
	 CFIBlksPerDev[CFIRegion] = (DWORDOUT(BlksRegion[CFIRegion]) & 0x00FF) + 1;
	 temp_Info->block_size[CFIRegion] =  (DWORDOUT(BlksRegion[CFIRegion])>>16) * 0x100;
     if (!temp_Info->block_size[CFIRegion])
         temp_Info->block_size[CFIRegion] = 128;

   }
#else
   /* Find block size and set in MEDIA_INFO ptr */
   CFIBlksPerDev = (DWORDOUT(BlksRegion) & 0x00FF) + 1;
   temp_Info->block_size = (DWORDOUT(BlksRegion)>>16) * 0x100;
    if (!temp_Info->block_size)
         temp_Info->block_size = 128;
#endif

   /* Parse device size and save */
   CFIDeviceSize = (DWORD)1 << BYTEOUT(DeviceSize);

   /* Get max number of bytes in multi-byte write */
   WriteQueueSize = (DWORD)1 << WORDOUT(WriteSize);

   /* DC/AC Params */
#if CFI_OPTIONAL
   MinVcc = (((BYTEOUT(MinVcc)&0xF0)>>4)*1000)+((BYTEOUT(MinVcc)&0x0F)*100);
   MaxVcc = (((BYTEOUT(MaxVcc)&0xF0)>>4)*1000)+((BYTEOUT(MaxVcc)&0x0F)*100);
   MinVpp = (((BYTEOUT(MinVpp)&0xF0)>>4)*1000)+((BYTEOUT(MinVpp)&0x0F)*100);
   MaxVpp = (((BYTEOUT(MaxVpp)&0xF0)>>4)*1000)+((BYTEOUT(MaxVpp)&0x0F)*100);
   TypBytePgmTime = (DWORD)1 << BYTEOUT(typBytePgmTime);
   TypBufferPgmTime = (DWORD)1 << BYTEOUT(typBufferPgmTime);
   if (TypBufferPgmTime == 1)
      TypBufferPgmTime = 0;
   TypBlockEraseTime = (DWORD)1 << BYTEOUT(typBlockEraseTime);
   TypChipEraseTime = (DWORD)1 << BYTEOUT(typChipEraseTime);
   if (TypChipEraseTime == 1)
      TypChipEraseTime = 0;
   MaxBytePgmTime = ((DWORD)1 << BYTEOUT(maxBytePgmTime))*TypBytePgmTime;
   MaxBufferPgmTime = ((DWORD)1 << BYTEOUT(maxBufferPgmTime))*TypBufferPgmTime;
   MaxBlockEraseTime = ((DWORD)1 << BYTEOUT(maxBlockEraseTime))*TypBlockEraseTime;
   MaxChipEraseTime = ((DWORD)1 << BYTEOUT(maxChipEraseTime))*TypChipEraseTime;

   PgmLoops  = TIME_LIMIT(MaxBufferPgmTime);
   EraseLoops = TIME_LIMIT(MaxBlockEraseTime);
   ChipEraseLoops = TIME_LIMIT(MaxChipEraseTime);
   if (!ChipEraseLoops)
      ChipEraseLoops = ERASE_TIME_LIMIT;
#endif

   if (HWImplement & ImplementPaired)
   {
#if !CFI_ERASE_REGIONS
     temp_Info->block_size <<= 1;
#else
     for (CFIRegion = 0; CFIRegion < temp_Info->number_regions; CFIRegion++)
     {
        temp_Info->block_size[CFIRegion] <<= 1;
     }
#endif
      CFIDeviceSize <<= 1;
      WriteQueueMask =  (WriteQueueSize << 1) - 1;
      WriteQueueCount = WriteQueueSize - 1;
      WriteQueueSize <<= 1;        /* Because of paired config */
   }
   else
   {
      WriteQueueMask = WriteQueueSize - 1;
      WriteQueueCount = (WriteQueueSize / 2) - 1;
   }

   temp_Info->media_type = 0x02;

   if ((CmdSet == CmdSetSCS) || (CmdSet == CmdSeti8Mb))
   {
      pointer = pointer0ed;

     CommandSetAddr = WORDOUT(CmdSetAddr);

      if (!(HWImplement & Implementx8))
         CommandSetAddr <<=1;

      if (HWImplement & ImplementPaired)
         CommandSetAddr <<=1;

      IncreasePtr(pointer, CommandSetAddr);

      VSx8paired = (VSx8PAIRED_STRUCT FAR_PTR)pointer;
      VSx8x16paired = (VSx8x16PAIRED_STRUCT FAR_PTR)pointer;

     EraseQueue = 0;
#if CFI_OPTIONAL
     ChipErase = 0;
     ProgramSuspend = 0;
     LockUnlock = 0;
     BlockLockStatusSupported = 0;
     BlockValidStatusSupported = 0;
#endif

      if (HWImplement & Implementx8x16)
      {
         if ((VSx8x16paired->Features[0] & EraseSuspendFlag) && (VSx8x16paired->Suspend[0]  == SuspendToWrite))
         temp_Info->media_type = 0;

         if (VSx8x16paired->Features[0] & EraseQueueFlag)
            EraseQueue = 1;

#if CFI_OPTIONAL
       if (VSx8x16paired->Features[0] & ChipEraseFlag)
         ChipErase = 1;

       if (VSx8x16paired->Features[0] & LockUnlockFlag)
         LockUnlock = 1;

       if (VSx8x16paired->Features[0] & ProgramSuspendFlag)
         ProgramSuspend = 1;

       OptVcc = (((VSx8x16paired->OptVcc[0]&0xF0)>>4)*1000)+(VSx8x16paired->OptVcc[0]&0x0F)*100;
       OptVpp = (((VSx8x16paired->OptVpp[0]&0xF0)>>4)*1000)+(VSx8x16paired->OptVpp[0]&0x0F)*100;

      if (VSx8x16paired->Status[0] & BlockLockStatusFlag)
         BlockLockStatusSupported = 1;
      if (VSx8x16paired->Status[0] & BlockValidStatusFlag)
         BlockValidStatusSupported = 1;

#endif
      }
      else
      {
         if ((VSx8paired->Features[0] & EraseSuspendFlag) && (VSx8paired->Suspend[0]  == SuspendToWrite))
         temp_Info->media_type = 0;

       if (VSx8paired->Features[0] & EraseQueueFlag)
            EraseQueue = 1;

#if CFI_OPTIONAL
       if (VSx8paired->Features[0] & ChipEraseFlag)
         ChipErase = 1;

       if (VSx8paired->Features[0] & LockUnlockFlag)
         LockUnlock = 1;

       if (VSx8paired->Features[0] & ProgramSuspendFlag)
         ProgramSuspend = 1;

       OptVcc = (((VSx8paired->OptVcc[0]&0xF0)>>4)*1000)+(VSx8paired->OptVcc[0]&0x0F)*100;
       OptVpp = (((VSx8paired->OptVpp[0]&0xF0)>>4)*1000)+(VSx8paired->OptVpp[0]&0x0F)*100;

      if (VSx8paired->Status[0] & BlockLockStatusFlag)
         BlockLockStatusSupported = 1;
      if (VSx8paired->Status[0] & BlockValidStatusFlag)
         BlockValidStatusSupported = 1;
#endif
     }
   }
   
#if CFI_OPTIONAL   
   if (LockUnlock)
   {
#if SEGMENTED
      *(WORD_PTR)&FlashLock  = (WORD)(CFITable[Offset].DeviceLock);
      *(WORD_PTR)&FlashUnlock  = (WORD)(CFITable[Offset].DeviceUnlock);
#else
      *(DWORD_PTR)&FlashLock  = (DWORD)(CFITable[Offset].DeviceLock);
      *(DWORD_PTR)&FlashUnlock  = (DWORD)(CFITable[Offset].DeviceUnlock);
#endif
   }
   else
   {
#if SEGMENTED
     *(WORD_PTR)&FlashLock  = (WORD)(0);
     *(WORD_PTR)&FlashUnlock  = (WORD)(0);
#else
     *(DWORD_PTR)&FlashLock  = 0x0;
     *(DWORD_PTR)&FlashUnlock  = 0x0;
#endif

   }
   if (ChipErase)
   {
#if SEGMENTED
      *(WORD_PTR)&FlashChipErase  = (WORD)(CFITable[Offset].DeviceChipErase);
#else
      *(DWORD_PTR)&FlashChipErase  = (DWORD)(CFITable[Offset].DeviceChipErase);
#endif
   }
   else
   {
#if SEGMENTED
     *(WORD_PTR)&FlashChipErase  = (WORD)(0);
#else
     *(DWORD_PTR)&FlashChipErase  = 0x0;
#endif
   }
#endif

   /* Now step through card to determine size */
   while (1)
   {
#if !CFI_ERASE_REGIONS
     temp_Info->number_blocks += CFIBlksPerDev;
#else
     for (CFIRegion = 0; CFIRegion < temp_Info->number_regions; CFIRegion++)
     {
        temp_Info->number_blocks[CFIRegion] += CFIBlksPerDev[CFIRegion];
     }
#endif

      temp_Info->media_size += CFIDeviceSize;

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

      if (HWImplement & Implementx8x16)
      {
         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))
         {
            *pointer0ed = FlashCommandRead*0x101;
            return(ERR_NONE);
         }

         IncreasePtr(pointer, (Address55h * 2));
         *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)))
         {
            *pointer0ed = FlashCommandRead*0x101;
            return(ERR_NONE);
         }
      }
      else
      {
         CFIx8paired = (CFIx8PAIRED_STRUCT FAR_PTR)pointer0ed;

         if (((BYTE)CFIx8paired->SignatureQ == (BYTE)LETTER_Q) &&
             ((BYTE)CFIx8paired->SignatureR == (BYTE)LETTER_R) &&
             ((BYTE)CFIx8paired->SignatureY == (BYTE)LETTER_Y))
         {
            *pointer0ed = FlashCommandRead*0x101;
            return(ERR_NONE);
         }

         DecreasePtr(pointer, (Address55h * 2));

         *pointer = FlashCommandQueryCFI*0x101;
         CFIx8paired = (CFIx8PAIRED_STRUCT FAR_PTR)pointer0ed;

         if (!(((BYTE)CFIx8paired->SignatureQ == (BYTE)LETTER_Q) &&
             ((BYTE)CFIx8paired->SignatureR == (BYTE)LETTER_R) &&
             ((BYTE)CFIx8paired->SignatureY == (BYTE)LETTER_Y)))
         {
            *pointer0ed = FlashCommandRead*0x101;
            return(ERR_NONE);
         }
      }
   return(ERR_NONE);
   }
}

/****************************************************************************
* Intel8MbSuspend                                                      Ver68
*
* FUNCTION:
*      Suspend any erase in progress, then leave the flash in read array
*      mode.
*
* FORMAT:
*      int Intel8MbSuspend(void)
*
* INPUTS:
*      The card must already be mapped at the desired address (i.e., caller
*      executes SlideMemoryWindow before calling).
*
* GLOBALS:
*      None
*
* CALLS:
*      None
*
* RETURNS:
*      ERR_NONE
*      Flash will be left in read-array mode.
****************************************************************************/
#if ERASE_BACKGROUND
WORD Intel8MbSuspend(void)
{
   FULL_WORD_PTR volatile pointer;

   pointer = (FULL_WORD_PTR)MC_ADDR;

   *pointer = FlashCommandStatus*0x101;   /* Get status from device */

   /* If both devices report back 80h, there is no erase in progress */
   /* Therefore, no need to suspend it.                              */
   if ((BYTE)(((*pointer & 0xFF00) >> 8) & (*pointer & 0x00FF)) != FlashStatusReady)
   {
      *pointer = FlashCommandSuspend*0x101;   /* Suspend it */
      /* Wait until the command takes effect - Get status, check it */
      while (!((BYTE)(((*pointer & 0xFF00) >> 8) & (*pointer & 0x00FF)) & FlashStatusReady))
      {
         *pointer = FlashCommandStatus*0x101;
      }

      /* Set it into read mode for use */
      *pointer = FlashCommandRead*0x101;
   }

   return (ERR_NONE);
}
/****************************************************************************
* Intel8MbResume                                                       Ver68
*
* FUNCTION:
*      Resume any suspended erase.
*
* FORMAT:
*      int Intel8MbResume(void)
*
* INPUTS:
*      The card must already be mapped at the desired address (i.e., caller
*      executes SlideMemoryWindow before calling).
*
* GLOBALS:
*      None
*
* CALLS:
*      None
*
* RETURNS:
*      Erase resumed, else flash left in read-array mode.
****************************************************************************/
WORD Intel8MbResume()
{
   FULL_WORD_PTR volatile pointer;

   pointer = (FULL_WORD_PTR)MC_ADDR;
   *pointer = FlashCommandRead*0x101;
   *pointer = FlashCommandResume*0x101;

   return (ERR_NONE);
}
/****************************************************************************
* Intel8MbStatus
*
* FUNCTION:
*      Respond with ERR_NONE if the flash is in the ready state, else
*      respond with ERR_BUSY.
*
* FORMAT:
*      int Intel8MbStatus(CardAddress)
*
* INPUTS:
*      dword   CardAddress     - address to check status
*
* GLOBALS:
*      None
*
* CALLS:
*      _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
*      ERR_NONE       - erase is complete and was successful
*      ERR_ERASE      - erase is complete but there was an error
*      ERR_BUSY       - erase is not yet complete
****************************************************************************/
WORD Intel8MbStatus(DWORD CardAddress)
{
   FULL_WORD_PTR volatile pointer;

⌨️ 快捷键说明

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