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

📄 lowlvl.c

📁 CF卡读卡程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Repositions a pointer to a different place in memory to access card.    */
/* It will slide the window to the area if the need arises, and then set   */
/* the pointer to the position either in the memory window, or if there is */
/* no windowing, simply sets the pointer position                          */
#define PositionPtr(Ptr,Addr)                                               \
   LowSlideWindow(Addr);                                                    \
   PointerAssignment(Ptr, Addr);

#define IncreasePtr(Ptr,Bytes) PointerAddition(Ptr, Bytes)
#define DecreasePtr(Ptr,Bytes) PointerSubtraction(Ptr, Bytes)


#if SWAP
/****************************************************************************
 * LSWAP
 *
 * FUNCTION: This function swaps the bytes in a DWORD. For example, if a DWORD
 *  containing FFEE8877 is inputted to this function, then LSWAP will output
 *  7788EEFF.
 *
 * INPUTS:
 *  x - Any DWORD
 *
 * GLOBALS:
 *  None
 *
 * OUTPUTS:
 *  See RETURNS section below
 *
 * CALLS:
 *  None
 *
 * FORMAT:
 *  DWORD LSWAP(DWORD);
 *
 * RETURNS:
 *  x - A swapped DWORD
 ***************************************************************************/
DWORD LSWAP(DWORD x)
{
   x = ((((x) & 0x000000ff) << 24) + \
       (((x) & 0x0000ff00) << 8)  + \
       (((x) & 0x00ff0000) >> 8)  + \
       (((x) & 0xff000000) >> 24));

   return x;
}

/****************************************************************************
 * BSWAP
 *
 * FUNCTION: This function swaps the bytes in a WORD. For example, if a WORD
 *  containing FF88 is inputted to this function, then BSWAP will output 88FF.
 *
 * INPUTS:
 *  x - A WORD
 *
 * GLOBALS:
 *  None
 *
 * OUTPUTS:
 *  See RETURNS section below
 *
 * CALLS:
 *  None
 *
 * FORMAT:
 *  WORD BSWAP(WORD);
 *
 * RETURNS:
 *  x - A swapped WORD
 ***************************************************************************/
   WORD BSWAP(WORD x)
   {
      x = (((WORD)((WORD)(x) << 8)) |
          ((WORD)((WORD)(x) >> 8)));

      return x;
   }
#endif

/****************************************************************************
* _FlashDevCompatCheck
*
* FUNCTION:
*      Upon card insertion, determine various card parameters (flash type,
*      card size, block size, number of blocks) and return them.
*
* INPUTS:
*      FTLTable ptr
*
* GLOBALS:
*      FlashRead       Address of flash read  routine
*      FlashWrite      Address of flash write routine
*      FlashErase      Address of flash erase routine
*      FlashSuspend    Address of flash suspend routine  Ver68
*      FlashResume     Address of flash resume routine   Ver68
*
* FORMAT:
*      int _FlashDevCompatCheck(FTLTable *)
*
* CALLS:
*      _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
*      If card identified successfully:
*              ERR_NONE
*              FTLTable ptr ->
*                      dword MediaSize         Size of card, in bytes
*                      dword MediaBlockSize    Size of flash block, in bytes
*                      int   MediaBlocks       Number of blocks
*                      byte  MediaType         WP, suspend capability, type
*      If card not identified:
*              ERR_JEDEC
****************************************************************************/
WORD FlashDevCompatCheck(MEDIA_INFO *temp_Info)
{
   FULL_WORD_PTR volatile WinAddress;/* Where in memory to access memory window */
   WORD Save16bits;        /* Where we will save info during detection */
   WORD JedecStore;        /* Place to keep Jedec_Id for searching */
   BYTE Method=0;
#if CFI_ERASE_REGIONS
   BYTE CFIRegions;
#endif

#if SEGMENTED
   FTLTablePtr = (WORD)temp_Info;  /* Set the pointer that PCIC.ASM uses for info */
#endif

   temp_Info->media_type = 0;   /* Set this to 0 right away */
   temp_Info->media_size = 0;   /* We will be setting this higher and */
                     /* higher as we go along..            */
#if !CFI_ERASE_REGIONS
   temp_Info->number_blocks = 0;
#else
   temp_Info->number_regions = 0;
   for (CFIRegions = 0; CFIRegions < MAX_ERASE_REGIONS; CFIRegions++)
   {
     temp_Info->number_blocks[CFIRegions] = 0;
     temp_Info->block_size[CFIRegions] = 0;
   }
#endif

   PositionPtr(WinAddress, temp_Info->media_size); /* Set pointer to base memory address */

   Save16bits = *WinAddress;             /* Save what is currently here */

   /* If CFI is there, then everything is fine, otherwise keep going with */
   /* Algorithm.                                                          */
   if (QueryCFI(temp_Info) == ERR_NONE)
   {
     temp_Info->manuf_id = 0x89;
     temp_Info->device_id = 0x00;
      return(ERR_NONE);
   }

   /* Issue Read command to clear things up */
   *WinAddress = FlashCommandRead*0x101;

   /* Issue word-sized old Intel ReadID command */
   *WinAddress = FlashCommandReadID*0x101;

   /* If SRAM, the contents will now be the ReadID value */
   if (*WinAddress == (WORD)FlashCommandReadID*0x101)
   {
#if SRAM_MEDIA
      /* It is SRAM, so now determine card size. */
      *WinAddress = Save16bits;         /* Restore the SRAM location */
     temp_Info->media_size = RAMSize(Save16bits); /* Call ramsize routine&set size */
     temp_Info->media_type = 0x01;                /* Set SRAM flag */

      /* Set up functions correctly for SRAM */
      FlashRead    = SRAMROMRead;
      FlashWrite   = SRAMWrite;
      FlashErase   = SRAMErase;
#if ERASE_BACKGROUND
      FlashSuspend = WriteProtectSusRes;
      FlashResume  = WriteProtectSusRes;
#endif

      /* We're all done, so exit with no error! */
      return(ERR_NONE);
#else
      return (ERR_JEDEC);
#endif
   }

   /* If value did not change, then try AMD compat check */
   if (*WinAddress == Save16bits)
   {
      /* Send Prefix1 to address AAAAh */
      SlideMemoryWindow(0xAAAA);
      WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
      *WinAddress = FlashCommandPrefix1*0x101;

      /* Send Prefix2 to address 5554h */
      SlideMemoryWindow(0x5554);
      WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0x5554));
      *WinAddress = FlashCommandPrefix2*0x101;

      /* Send ReadID to address AAAAh */
      SlideMemoryWindow(0xAAAA);
      WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
      *WinAddress = FlashCommandReadID*0x101;

      SlideMemoryWindow(0);
      WinAddress = (FULL_WORD_PTR)MC_ADDR;

      /* If not responding, must be ROM (write-protected) */
      if (*WinAddress == Save16bits)
      {
       temp_Info->media_type |= 0x04;

       /* Set up function pointers for ROM (can't do much) */
         FlashRead    = SRAMROMRead;
         FlashWrite   = WriteProtectWrite;
         FlashErase   = WriteProtectErase;
#if ERASE_BACKGROUND
         FlashSuspend = WriteProtectSusRes;
         FlashResume  = WriteProtectSusRes;
#endif
         /* We're all done, so exit with no error! */
         return(ERR_NONE);
      }

      Method = 1;   /* If 1, means to use this, if 0 (default), use ReadID */
   }

   /* Get the JEDEC ID and store it */
   temp_Info->manuf_id = *WinAddress;
   temp_Info->device_id = *(WinAddress+1);
   JedecStore = (temp_Info->manuf_id << 8) | temp_Info->device_id;

   /* Here we scroll through the table trying to match the JEDEC_ID to
      something in it. */
   Offset=0;
   while(FlashTechnologyTable[Offset].Device_JEDEC != 0xFFFF)
   {
      if (FlashTechnologyTable[Offset].Device_JEDEC == JedecStore)
         break;
      Offset++;
   }
   if (FlashTechnologyTable[Offset].Device_JEDEC == 0xFFFF)
      return (ERR_JEDEC);

   /* If we have gotten this far we have identified the device in the  */
   /* TechnologyTable, and can load the Media_Info passed in with info */

   /* Load block size */
#if !CFI_ERASE_REGIONS
   temp_Info->block_size = FlashTechnologyTable[Offset].DeviceBlockSize;
#else
   temp_Info->number_regions = 1;
   temp_Info->block_size[0] = FlashTechnologyTable[Offset].DeviceBlockSize;
#endif

   /* Set suspend capability */
   temp_Info->media_type |= 0x02;     /* Turn off suspend */

   if (FlashTechnologyTable[Offset].DeviceCapabilities & 0x3)
      temp_Info->media_type &= 0xFD;

   /* Set up pointers for functions based on table values */
#if SEGMENTED
   *(WORD_PTR)&FlashRead    = (WORD)(FlashTechnologyTable[Offset].DeviceRead);
   *(WORD_PTR)&FlashWrite   = (WORD)(FlashTechnologyTable[Offset].DeviceWrite);
   *(WORD_PTR)&FlashErase   = (WORD)(FlashTechnologyTable[Offset].DeviceErase);
#if ERASE_BACKGROUND
   *(WORD_PTR)&FlashStatus  = (WORD)FlashTechnologyTable[Offset].DeviceStatus;
   *(WORD_PTR)&FlashSuspend = (WORD)FlashTechnologyTable[Offset].DeviceSuspend;
   *(WORD_PTR)&FlashResume  = (WORD)FlashTechnologyTable[Offset].DeviceResume;
#endif
#else
   *(DWORD_PTR)&FlashRead    = (DWORD)(FlashTechnologyTable[Offset].DeviceRead);
   *(DWORD_PTR)&FlashWrite   = (DWORD)(FlashTechnologyTable[Offset].DeviceWrite);
   *(DWORD_PTR)&FlashErase   = (DWORD)(FlashTechnologyTable[Offset].DeviceErase);
#if ERASE_BACKGROUND
   *(DWORD_PTR)&FlashStatus  = (DWORD)FlashTechnologyTable[Offset].DeviceStatus;
   *(DWORD_PTR)&FlashSuspend = (DWORD)FlashTechnologyTable[Offset].DeviceSuspend;
   *(DWORD_PTR)&FlashResume  = (DWORD)FlashTechnologyTable[Offset].DeviceResume;
#endif
#endif
   while(1)
   {
      /* One device has come and gone, so add it's sizes on. */
     temp_Info->media_size    += FlashTechnologyTable[Offset].DeviceSize;
#if !CFI_ERASE_REGIONS
     temp_Info->number_blocks += FlashTechnologyTable[Offset].DeviceBlocks;
#else
     temp_Info->number_blocks[0] += FlashTechnologyTable[Offset].DeviceBlocks;
#endif

     /* Set window to next device */
     PositionPtr(WinAddress, temp_Info->media_size);

      /* If device is in ReadID mode, then this is the first one again */
      if (((*WinAddress & 0xFF00) + (*(WinAddress+1) & 0x00FF)) == JedecStore)
      {
          *WinAddress = FlashCommandRead*0x101;
         return (ERR_NONE);
      }

      if (Method)             /* If need to use AMD method */
      {
         /* Send Prefix1 to address AAAAh */
       SlideMemoryWindow(temp_Info->media_size + 0xAAAA);
         WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
         *WinAddress = FlashCommandPrefix1*0x101;

         /* Send Prefix2 to address 5554h */
       SlideMemoryWindow(temp_Info->media_size + 0x5554);
         WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0x5554));
         *WinAddress = FlashCommandPrefix2*0x101;

         /* Send ReadID to address AAAAh */
       SlideMemoryWindow(temp_Info->media_size + 0xAAAA);
         WinAddress = (FULL_WORD_PTR)MC_ADDR + (MC_WIND_MSK & 0xAAAA);
         *WinAddress = FlashCommandReadID*0x101;
      }
      else                    /* Else use Intelligent Identifier method */
      {
         *WinAddress = FlashCommandReadID*0x101;
      }

      /* If there is no Jedec here, then the card does not map around to 0 */
      /* When accessed over card size, therefore we are at the end.       */
      if (((*WinAddress & 0xFF00) + (*(WinAddress+1) & 0x00FF)) != JedecStore)
      {
         return (ERR_NONE);
     }

      /* Otherwise, set device back to read mode and continue */
      *WinAddress = FlashCommandRead*0x101;
      return(ERR_NONE);
   }
   
}

#if SRAM_MEDIA
/****************************************************************************
* RAMSize
*
* FUNCTION:
*      Determine the size of a RAM card.  Load it into temp_Info->MediaSize
*
* INPUTS:
*      Original Word at address 0;
*
* FORMAT:
*      RAMSize(WORD)
*
* CALLS:
*      _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
*      dword Size                       Size of card, in bytes
****************************************************************************/
DWORD RAMSize(WORD OriginalWord)
{
   FULL_WORD_PTR volatile pointer;
   WORD SaveWord, SaveTest;
   /* Start up at 64k */
   DWORD Size=0;

   while (1)
   {
      /* Move upward by 10000h increments, checking each time */
      Size += 0x10000;
      PositionPtr(pointer, Size);

      /* Get a word from this position, and XOR it */
      SaveWord = (*pointer ^= 0xFFFF);

      /* Write, then check to see if it changed. If not, we are done. */
      *pointer = SaveWord;
      if (*pointer == SaveWord) return (Size);

      SaveWord ^= 0xFFFF;     /* Return SaveWord to original state */

      /* If this word == word at address 0, possibility exists we wrapped */
      if (SaveWord == OriginalWord)
      {
         PositionPtr(pointer, 0);
         SaveTest = *pointer;
         PositionPtr(pointer, Size);
         *pointer = OriginalWord;
         OriginalWord ^= 0xFFFF;

⌨️ 快捷键说明

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