📄 nor.c
字号:
flash_write_cmd(blkAddr,0,INTEL_LOCK_BLOCK_CMD);
// Check Status
return Intel_Lock_Status_Check();
}
void Intel_Wait_For_Status_Complete()
{
while ( !flash_issetall(gNorInfo.flashBase, 0, BIT7) );
}
Uint32 Intel_Lock_Status_Check()
{
Uint32 retval = E_PASS;
//Uint8 status;
Intel_Wait_For_Status_Complete();
//status = flash_read_uint16((Uint32)gNorInfo.flashBase,0);
//if ( status & BIT5 )
if (flash_issetsome(gNorInfo.flashBase, 0, (BIT5 | BIT3)))
{
retval = E_FAIL;
/*if ( status & BIT4 )
{
UARTSendData("Command Sequence Error\r\n", FALSE);
}
else
{
UARTSendData("Clear Lock Error\r\n", FALSE);
}*/
}
/*if ( status & BIT3 )
{
retval = E_FAIL;
//UARTSendData("Voltage Range Error\n", FALSE);
}*/
// Clear status
Intel_Clear_Status();
// Put chip back into read array mode.
Intel_Soft_Reset_Flash();
// Set Timings back to Optimum for Read
return retval;
}
// Erase Block
Uint32 Intel_Erase(VUint32 blkAddr)
{
Uint32 retval = E_PASS;
// Clear Lock Bits
retval |= Intel_Clear_Lock(blkAddr);
// Send Erase commands
flash_write_cmd(blkAddr,0,INTEL_ERASE_CMD0);
flash_write_cmd(blkAddr,0,INTEL_ERASE_CMD1);
// Wait until Erase operation complete
Intel_Wait_For_Status_Complete();
// Verify successful erase
if ( flash_issetsome(gNorInfo.flashBase, 0, BIT5) )
retval = E_FAIL;
// Put back into Read Array mode.
Intel_Soft_Reset_Flash();
return retval;
}
// Write data
Uint32 Intel_Write( Uint32 address, VUint32 data )
{
Uint32 retval = E_PASS;
// Send Write command
flash_write_cmd(address,0,INTEL_WRITE_CMD);
flash_write_data(address, data);
// Wait until Write operation complete
Intel_Wait_For_Status_Complete();
// Verify successful program
if ( flash_issetsome(gNorInfo.flashBase, 0, (BIT4|BIT3)) )
{
//UARTSendData("Write Op Failed.\r\n", FALSE);
retval = E_FAIL;
}
// Lock the block
//retval |= Intel_Set_Lock(blkAddr);
// Put back into Read Array mode.
Intel_Soft_Reset_Flash();
return retval;
}
// Buffer write data
Uint32 Intel_BufferWrite(Uint32 address, VUint8 data[], Uint32 numBytes )
{
Uint32 startAddress = address;
Uint32 retval = E_PASS;
Uint32 timeoutCnt = 0, shift;
// Send Write_Buff_Load command
do {
flash_write_cmd(address,0,INTEL_WRT_BUF_LOAD_CMD);
timeoutCnt++;
}while( (!flash_issetall(gNorInfo.flashBase, 0, BIT7)) && (timeoutCnt < 0x00010000) );
if (timeoutCnt >= 0x10000)
{
// UARTSendData("Write Op Failed.\r\n", FALSE);
retval = E_TIMEOUT;
}
else
{
//Establish correct shift value
shift = 0;
while ((gNorInfo.busWidth >> shift) > 1)
shift++;
// Write Length (either numBytes or numBytes/2)
flash_write_cmd(startAddress, 0, (numBytes >> shift) - 1);
// Write buffer length
//flash_write_data(startAddress, (length - 1));
// Write buffer data
flash_write_databuffer(&address,(void*)data,numBytes);
// Send write buffer confirm command
flash_write_cmd(startAddress,0,INTEL_WRT_BUF_CONF_CMD);
// Check status
Intel_Wait_For_Status_Complete();
// Verify program was successful
//if ( flash_read_uint8(gNorInfo.flashBase,0) & BIT4 )
if ( flash_issetsome(gNorInfo.flashBase, 0, BIT4) )
{
// UARTSendData("Write Buffer Op Failed.\r\n", FALSE);
retval = E_FAIL;
}
// Put back into Read Array mode.
Intel_Soft_Reset_Flash();
}
return retval;
}
// -------------------- End of Intel specific commands ----------------------
// -------------------- Begin of AMD specific commands -----------------------
// Identify the Manufacturer and Device ID
Uint32 AMD_ID( Uint32 baseAddress )
{
// Exit back to read array mode
AMD_Soft_Reset_Flash();
// Write ID commands
AMD_Prefix_Commands();
flash_write_cmd(baseAddress, AMD_CMD2_ADDR, AMD_ID_CMD);
// Read manufacturer's ID
gNorInfo.manfID = (MANFID) flash_read_data(baseAddress, AMD_MANFID_ADDR);
// Read device ID
gNorInfo.devID1 = (Uint16) flash_read_data(baseAddress, AMD_DEVID_ADDR0);
// Read additional ID bytes if needed
if ( (gNorInfo.devID1 & 0xFF ) == AMD_ID_MULTI )
gNorInfo.devID2 = flash_read_CFI_bytes(baseAddress, AMD_DEVID_ADDR1, 2).w;
else
gNorInfo.devID2 = 0x0000;
// Exit back to read array mode
AMD_Soft_Reset_Flash();
return E_PASS;
}
void AMD_Soft_Reset_Flash()
{
// Reset Flash to be in Read Array Mode
flash_write_cmd(gNorInfo.flashBase,AMD_CMD2_ADDR,AMD_RESET);
}
// AMD Prefix Commands
void AMD_Prefix_Commands()
{
flash_write_cmd(gNorInfo.flashBase, AMD_CMD0_ADDR, AMD_CMD0);
flash_write_cmd(gNorInfo.flashBase, AMD_CMD1_ADDR, AMD_CMD1);
}
// Erase Block
Uint32 AMD_Erase(Uint32 blkAddr)
{
Uint32 retval = E_PASS;
// Send commands
AMD_Prefix_Commands();
flash_write_cmd(gNorInfo.flashBase, AMD_CMD2_ADDR, AMD_BLK_ERASE_SETUP_CMD);
AMD_Prefix_Commands();
flash_write_cmd(blkAddr, AMD_CMD2_ADDR, AMD_BLK_ERASE_CMD);
// Poll DQ7 and DQ15 for status
while ( !flash_issetall(blkAddr, 0, BIT7) );
// Check data
if ( !flash_data_isequal(blkAddr, 0, AMD_BLK_ERASE_DONE) )
retval = E_FAIL;
/* Flash Mode: Read Array */
AMD_Soft_Reset_Flash();
return retval;
}
// AMD Flash Write
Uint32 AMD_Write( Uint32 address, VUint32 data )
{
Uint32 retval = E_PASS;
// Send Commands
AMD_Prefix_Commands();
flash_write_cmd(gNorInfo.flashBase, AMD_CMD2_ADDR, AMD_PROG_CMD);
flash_write_data(address, data);
// Wait for ready.
while(TRUE)
{
if ( (flash_read_data(address, 0 ) & (BIT7 | BIT15) ) == (data & (BIT7 | BIT15) ) )
{
break;
}
else
{
if(flash_issetall(address, 0, BIT5))
{
if ( (flash_read_data(address, 0 ) & (BIT7 | BIT15) ) != (data & (BIT7 | BIT15) ) )
{
UARTSendData("Timeout ocurred.\r\n",FALSE);
retval = E_FAIL;
}
break;
}
}
}
// Return Read Mode
AMD_Soft_Reset_Flash();
// Verify the data.
if ( (retval == E_PASS) && ( flash_read_data(address, 0) != data) )
retval = E_FAIL;
return retval;
}
// AMD flash buffered write
Uint32 AMD_BufferWrite(Uint32 address, VUint8 data[], Uint32 numBytes )
{
Uint32 startAddress = address;
Uint32 blkAddress, blkSize;
Uint32 data_temp;
Uint32 retval = E_PASS;
Uint32 shift;
// Get block base address and size
DiscoverBlockInfo(address, &blkSize, &blkAddress);
// Write the Write Buffer Load command
AMD_Prefix_Commands();
flash_write_cmd(blkAddress, 0, AMD_WRT_BUF_LOAD_CMD);
//Establish correct shift value
shift = 0;
while ((gNorInfo.busWidth >> shift) > 1)
shift++;
// Write Length (either numBytes or numBytes/2)
flash_write_cmd(blkAddress, 0, (numBytes >> shift) - 1);
// Write Data
flash_write_databuffer(&address,(void*)data, numBytes);
// Program Buffer to Flash Confirm Write
flash_write_cmd(blkAddress, 0, AMD_WRT_BUF_CONF_CMD);
// Read last data item
data_temp = flash_read_data((Uint32) (data + (address - startAddress)), 0);
while(TRUE)
{
//temp1 = flash_read_data(address, 0 );
if( (flash_read_data(address, 0 ) & (BIT7 | BIT15)) == (data_temp & (BIT7 | BIT15) ) )
{
break;
}
else
{
// Timeout has occurred
if(flash_issetall(address, 0, BIT5))
{
if( (flash_read_data(address, 0 ) & (BIT7 | BIT15)) != (data_temp & (BIT7 | BIT15) ) )
{
UARTSendData("Timeout ocurred.\r\n",FALSE);
retval = E_FAIL;
}
break;
}
// Abort has occurred
if(flash_issetall(address, 0, BIT1))
{
if( (flash_read_data(address, 0 ) & (BIT7 | BIT15)) != (data_temp & (BIT7 | BIT15) ) )
{
UARTSendData("Abort ocurred.\r\n",FALSE);
retval = E_FAIL;
AMD_Write_Buf_Abort_Reset_Flash ();
}
break;
}
}
}
// Put chip back into read array mode.
AMD_Soft_Reset_Flash();
if (retval == E_PASS)
retval = flash_verify_databuffer(startAddress,(void*)data, numBytes);
return retval;
}
// AMD Write Buf Abort Reset Flash
void AMD_Write_Buf_Abort_Reset_Flash()
{
// Reset Flash to be in Read Array Mode
AMD_Prefix_Commands();
AMD_Soft_Reset_Flash();
}
//--------------------- End of AMD specific commands ------------------------
// Get info on block address and sizes
Uint32 DiscoverBlockInfo(Uint32 address,Uint32* blockSize, Uint32* blockAddr)
{
Int32 i;
Uint32 currRegionAddr, nextRegionAddr;
currRegionAddr = (Uint32) gNorInfo.flashBase;
if ((address < currRegionAddr) || (address >= (currRegionAddr+gNorInfo.flashSize)))
{
return E_FAIL;
}
for(i=0; i< (gNorInfo.numberRegions); i++)
{
nextRegionAddr = currRegionAddr + (gNorInfo.blockSize[i] * gNorInfo.numberBlocks[i]);
if ( (currRegionAddr <= address) && (nextRegionAddr > address) )
{
*blockSize = gNorInfo.blockSize[i];
*blockAddr = address & (~((*blockSize) - 1));
break;
}
currRegionAddr = nextRegionAddr;
}
return E_PASS;
}
// --------------------------- NOR API Functions -----------------------------
//Global Erase NOR Flash
Uint32 NOR_GlobalErase()
{
return NOR_Erase( (VUint32) gNorInfo.flashBase, (VUint32) gNorInfo.flashSize );
}
// Erase Flash Block
Uint32 NOR_Erase(VUint32 start_address, VUint32 size)
{
VUint32 addr = start_address;
VUint32 range = start_address + size;
Uint32 blockSize, blockAddr;
UARTSendData((Uint8 *)"Erasing the NOR Flash\r\n", FALSE);
while (addr < range)
{
if (DiscoverBlockInfo(addr, &blockSize, &blockAddr) != E_PASS)
{
UARTSendData((Uint8 *)"Address out of range", FALSE);
return E_FAIL;
}
//Increment to the next block
if ( (*Flash_Erase)(blockAddr) != E_PASS)
{
UARTSendData("Erase failure at block address 0x",FALSE);
UARTSendInt(blockAddr);
UARTSendData("\r\n", FALSE);
return E_FAIL;
}
addr = blockAddr + blockSize;
// Show status messages
UARTSendData((Uint8 *)"Erased through 0x", FALSE);
UARTSendInt(addr);
UARTSendData((Uint8 *)"\r\n", FALSE);
}
UARTSendData((Uint8 *)"Erase Completed\r\n", FALSE);
return(E_PASS);
}
// NOR_WriteBytes
Uint32 NOR_WriteBytes( Uint32 writeAddress,
Uint32 numBytes,
Uint32 readAddress)
{
Uint32 blockSize, blockAddr;
Int32 i;
Uint32 retval = E_PASS;
UARTSendData((Uint8 *)"Writing the NOR Flash\r\n", FALSE);
// Make numBytes even if needed
if (numBytes & 0x00000001)
numBytes++;
if (DiscoverBlockInfo(writeAddress, &blockSize, &blockAddr) != E_PASS)
{
UARTSendData((Uint8 *)"Address out of range", FALSE);
return E_FAIL;
}
while (numBytes > 0)
{
if( (numBytes < gNorInfo.bufferSize) || (writeAddress & (gNorInfo.bufferSize-1) ))
{
if ((*Flash_Write)(writeAddress, flash_read_data(readAddress,0) ) != E_PASS)
{
UARTSendData("\r\nNormal Write Failed.\r\n", FALSE);
retval = E_FAIL;
}
else
{
numBytes -= gNorInfo.busWidth;
writeAddress += gNorInfo.busWidth;
readAddress += gNorInfo.busWidth;
}
}
else
{
// Try to use buffered writes
if((*Flash_BufferWrite)(writeAddress, (VUint8 *)readAddress, gNorInfo.bufferSize) == E_PASS)
{
numBytes -= gNorInfo.bufferSize;
writeAddress += gNorInfo.bufferSize;
readAddress += gNorInfo.bufferSize;
}
else
{
// Try normal writes as a backup
for(i = 0; i<(gNorInfo.bufferSize>>1); i++)
{
if ((*Flash_Write)(writeAddress, flash_read_data(readAddress,0) ) != E_PASS)
{
UARTSendData("\r\nNormal write also failed\r\n", FALSE);
retval = E_FAIL;
break;
}
else
{
numBytes -= gNorInfo.busWidth;
writeAddress += gNorInfo.busWidth;
readAddress += gNorInfo.busWidth;
}
}
}
}
// Output status info on the write operation
if (retval == E_PASS)
{
if ( ((writeAddress & (~((blockSize>>4)-1))) == writeAddress) || (numBytes == 0) )
{
UARTSendData((Uint8*) "NOR Write OK through 0x", FALSE);
UARTSendInt(writeAddress);
UARTSendData((Uint8*)"\r\n", FALSE);
if (DiscoverBlockInfo(writeAddress, &blockSize, &blockAddr) != E_PASS)
{
UARTSendData((Uint8 *)"Address out of range", FALSE);
return E_FAIL;
}
}
}
else
{
UARTSendData((Uint8*) "NOR Write Failed...Aborting!\r\n", FALSE);
return E_FAIL;
}
}
return retval;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -