📄 lowlvl.c
字号:
*(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 + -