📄 flashwriternor.c
字号:
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
}
else if (addr_without_cs < 0x800000)
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
break;
case FLASH_INTEL_STRATA_J3_4MB: // 2 4MB devices=8MB
if (addr_without_cs >= 0x800000)
{// return ERROR
return(0);
}
// round down to next block
addr &= 0xFFFE0000;
block_size = 0x20000;
break;
case FLASH_INTEL_STRATA_J3_8MB: // 2 8MB devices=16MB
if (addr_without_cs >= 0x1000000) // return ERROR
{
return(0);
}
// round down to the next block
addr &= 0xFFFE0000;
block_size = 0x20000;
break;
case FLASH_INTEL_STRATA_J3_16MB: // 2 16MB devices=32MB
if (addr_without_cs >= 0x2000000) // return ERROR
{
return(0);
}
// round down to next block
addr &= 0xFFFE0000;
block_size = 0x20000;
break;
case FLASH_INTEL_STRATA_K3_16MB: // 16MB devices=32MB
if (addr_without_cs >= 0x2000000) // return ERROR
{
return(0);
}
// round down to next block
addr &= 0xFFFE0000;
block_size = 0x20000;
break;
case FLASH_INTEL_W18_16MB_BOTTOM:
if (addr_without_cs >= 0x1000000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x10000)
{
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
}
else
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
break;
case FLASH_INTEL_W18_16MB_TOP:
if (addr_without_cs >= 0x1000000) // return ERROR
{
return(0);
}
if (addr_without_cs > 0x7F7FFF)
{
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
} else
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
break;
case FLASH_INTEL_L18_16MB_BOTTOM:
if (addr_without_cs >= 0x1000000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x20000)
{
block_size = 0x8000;
// round down to next block
addr &= 0xFFFF8000;
}
else
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
break;
case FLASH_INTEL_K18_32MB_BOTTOM:
case FLASH_INTEL_L18_32MB_BOTTOM:
if (addr_without_cs >= 0x2000000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x20000)
{
block_size = 0x8000; //32 kBytes blocks
// round down to next block
addr &= 0xFFFF8000;
}
else
{
block_size = 0x20000; //128 kBytes Blocks
// round down to next block
addr &= 0xFFFE0000;
}
break;
case FLASH_INTEL_L18_32MB_TOP:
if (addr_without_cs >= 0x2000000) // return ERROR
{
return(0);
}
if (addr_without_cs >= 0x1FE0000)
{
block_size = 0x8000; //32 kBytes blocks
// round down to next block
addr &= 0xFFFF8000;
}
else
{
block_size = 0x20000; //128 kBytes Blocks
// round down to next block
addr &= 0xFFFE0000;
}
break;
}
//Increment to the next block
User_Flash_Erase_Block(addr);
addr += block_size;
printf("Erased up to address 0x%08X\n", addr);
}
return(0);
}
///////////////////////////////////////////////////////////////////////////////
//
// Flash Do Nothing
//
// Description:
// This routine does absolutely nothing. BUT, it does it really well!
//
///////////////////////////////////////////////////////////////////////////////
void Flash_Do_Nothing(void)
{
return;
}
///////////////////////////////////////////////////////////////////////////////
// INTEL Flash Erase Block
//
// Description:
// This routine erases the Intel Flash block specified by the input
// parameter address.
//
// Arguments:
// address - address in block to be erased
///////////////////////////////////////////////////////////////////////////////
void INTEL_Flash_Erase_Block(ULONG address)
{
// Clear Lock Bits
INTEL_Clear_Lock_Bits(address);
*((vHwdptr)address) = 0x0020; //INTEL_ERASE_CMD0
*((vHwdptr)address) = 0x00D0; //INTEL_ERASE_CMD1
while (!(*((vHwdptr)address) & 0x0080)); //Erase Done
// Put back into Read Array mode.
*((vHwdptr)address) = 0x00FF; //INTEL_READ_MODE;
}
///////////////////////////////////////////////////////////////////////////////
//
// INTEL Flash Write
//
// Description:
// This routine writes data to flash memory starting at the specified
// parameter address.
//
// Arguments:
// plAddress - address to be erased
// ulData - data to be written
//
// Return:
// int - 0 Success
// - 1 Fail
//
///////////////////////////////////////////////////////////////////////////////
int INTEL_Flash_Write( ULONG *plAddress, USHORT ulData )
{
volatile USHORT *psAddress;
// Lower WORD.
psAddress = (USHORT *)plAddress;
// Write the program setup command (0x40), then the data.
*psAddress = 0x0040;
*psAddress = ulData;
// Wait for ready.
while ( !( *psAddress & 0x0080 ));
// Check program status.
if ( *psAddress & 0x0010 )
{
INTEL_Soft_Reset_Flash((ULONG) psAddress);
return 1;
}
// Put chip back into read array mode.
*psAddress = 0x00FF;
// Verify the data.
if ( *psAddress != ulData )
{
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psAddress);
return 1;
}
// Set Timings back to Optimum for Read
return 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// Intel Soft Reset Flash
//
// Description:
// Resets the flash device internally (i.e. a software reset).
//
// C Syntax:
// void INTEL_Soft_Reset_Flash(ULONG addr);
//
// Arguments:
// r0: Any valid address in a flash memory bank.
//
// Notes:
// Callable from C. Registers r0-r3 are *not* preserved.
//
///////////////////////////////////////////////////////////////////////////////
void INTEL_Soft_Reset_Flash(ULONG addr)
{
// Reset Flash to be in Read Array Mode
*((vHwdptr) addr) = 0x00FF;
// Since we use this routine before we have identified the Flash type and
// we have to access both sets of Flashes, we go ahead and access
// 16 MB offsets. This should not be detrimental.
//*((vHwdptr) addr + N8MB) = 0x00FF;
*((vHwdptr) addr + N16MB) = 0x00FF;
// return to caller
}
///////////////////////////////////////////////////////////////////////////////
//
// INTEL Set Lock Bits
//
// Description:
// This routine sets all lock bits at the Flash Block Address
//
// Arguments:
// psAddress - block address to be locked
//
// Return:
// int - 0 Success
// - 1 Fail
//
///////////////////////////////////////////////////////////////////////////////
int INTEL_Set_Lock_Bit(USHORT *plAddress)
{
int retval = 0;
volatile USHORT *psAddress;
psAddress = plAddress;
// Write the lock Bits Command
*psAddress = 0x0060;
*psAddress = 0x0001;
while(!(*psAddress & BIT7));
if(*psAddress & BIT4)
{
retval = 1;
if(*psAddress & BIT5)
{
printf("Command Sequence Error\n");
}
else
{
printf("Set Lock-Bit Error\n");
}
*psAddress = 0x0050; // Clear Status Register
}
if(*psAddress & BIT3)
{
retval = 1;
printf("Voltage Range Error\n");
*psAddress = 0x0050; // Clear Status Register
}
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psAddress);
// Set Timings back to Optimum for Read
// InitEMIFSlow(STRATA_READ);
return retval ;
}
///////////////////////////////////////////////////////////////////////////////
//
// INTEL Clear Lock Bits
//
// Description:
// This routine clears all lock bits in the Flash
//
// Arguments:
// plAddress - address to be erased
//
// Return:
// int - 0 Success
// - 1 Fail
//
///////////////////////////////////////////////////////////////////////////////
int INTEL_Clear_Lock_Bits(USHORT *plAddress)
{
int retval = 0;
volatile USHORT *psAddress;
psAddress = plAddress;
// Adjust the timings for Writes
// InitEMIFSlow(STRATA_WRITE);
// Write the Clear Bits Command
*psAddress = 0x0060;
*psAddress = 0x00D0;
// Read Status Register
while(!(*psAddress & BIT7));
if(*psAddress & BIT5)
{
retval = 1;
if(*psAddress & BIT4)
{
printf("Command Sequence Error\n");
}
else
{
printf("Clear Lock-Bit Error\n");
}
*psAddress = 0x0050; // Clear Status Register
}
if(*psAddress & BIT3)
{
retval = 1;
printf("Voltage Range Error\n");
*psAddress = 0x0050; // Clear Status Register
}
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psAddress);
// Set Timings back to Optimum for Read
return retval ;
}
///////////////////////////////////////////////////////////////////////////////
//
// INTEL Flash Optimized Write
//
// Description:
// This routine writes an array of data to flash memory starting beginning
// at the specified parameter address.
//
// Arguments:
// plAddress - address to begin writing
// ulData[] - data array to be written
// length - length of data array
//
// Return:
// int - 0 Success
// - 1 Fail
//
///////////////////////////////////////////////////////////////////////////////
int INTEL_Flash_Optimized_Write(ULONG *plAddress, USHORT ulData[], ULONG ullength )
{
volatile USHORT *psAddress;
volatile USHORT *psBlockAddress;
ULONG tmp_ptr;
int write_buffer_timeout= 1000000; // A million times seems reasonable enough
USHORT i; // to obtain a write buffer
// Adjust the timings for Writes
tmp_ptr = (ULONG) plAddress;
psAddress = (USHORT *)plAddress;
// Block Address WORD.
psBlockAddress = (USHORT *)(tmp_ptr &= 0xFFFE0000);
// Write the program setup command (0xE8), and wait for Buffer available
do
{
*psBlockAddress = 0x00E8;
write_buffer_timeout--;
if(write_buffer_timeout == 0)
{
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psBlockAddress);
return 1;
}
} while(!(*psBlockAddress & BIT7));
// Write Length
*psBlockAddress = (USHORT) (ullength-1);
// Write Data
for(i=0; i<ullength; i++)
{
*psAddress = ulData[i];
psAddress++;
}
// Program Buffer to Flash Confirm Write
*psBlockAddress = 0x00D0;
psAddress = (USHORT *)plAddress; // To be valid address (could fall outside of CS range
// Wait for Write State Machine
*psAddress = 0x0070; // Check Status Register
while(!(*psAddress & BIT7));
// Check program status.
if ( *psAddress & 0x0010 )
{
// Clear Status
*psAddress = 0x0050;
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psBlockAddress);
return 1;
}
// Put chip back into read array mode.
INTEL_Soft_Reset_Flash((ULONG) psBlockAddress);
// Verify Written Data
psAddress = (USHORT *)plAddress;
for(i=0; i<ullength; i++)
{
if(*psAddress != ulData[i])
{
return 1;
}
psAddress++;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// AMD Soft Reset Flash
//
// Description:
// Resets the flash device internally (i.e. a software reset).
// C Syntax:
// void AMD_Soft_Reset_Flash(ULONG addr);
// Arguments:
// r0: Any valid address in a flash memory bank.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -