📄 ssiflash.c
字号:
pucBuffer[0] = (unsigned char)((ulAddress >> 16) & 0xFF);
pucBuffer[1] = (unsigned char)((ulAddress >> 8) & 0xFF);
pucBuffer[2] = (unsigned char)(ulAddress & 0xFF);
SSIFlashInstructionWrite(INSTR_SECTOR_ERASE, pucBuffer, 3);
SSIFlashInstructionEnd();
//
// Wait for the instruction to complete if the function is being called
// synchronously.
//
if(bSync)
{
bRetcode = SSIFlashIdleWait(MAX_BUSY_POLL_ERASE_SECTOR);
}
//
// Tell the caller how things went.
//
return(bRetcode);
}
//*****************************************************************************
//
//! Erases the contents of a single serial flash block.
//!
//! \param ulAddress is the start address of the block which is to be erased.
//! This value must be an integer multiple of the block size returned
//! by SSIFlashBlockSizeGet().
//! \param bSync should be set to \b true if the function is to block until
//! the erase operation is complete or \b false to return immediately after
//! the operation is started.
//!
//! This function erases a single block of the serial flash, returning all
//! bytes in that block to their erased value of 0xFF. The block size and,
//! hence, start address granularity can be determined by calling
//! SSIFlashBlockSizeGet().
//!
//! The function may be synchronous (\e bSync set to \b true) or asynchronous
//! (\e bSync set to \b false). If asynchronous, the caller is responsible for
//! ensuring that no further serial flash operations are requested until the
//! erase operation has completed. The state of the device may be queried by
//! calling SSIFlashIsBusy().
//!
//! Three options for erasing are provided. Sectors provide the smallest
//! erase granularity, blocks provide the option of erasing a larger section of
//! the device in one operation and, finally, the whole device may be erased
//! in a single operation via SSIFlashChipErase().
//!
//! \note This operation will take between 400mS and 1000mS to complete. If the
//! \e bSync parameter is set to \b true, this function will, therefore, not
//! not return for a significant period of time.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
tBoolean
SSIFlashBlockErase(unsigned long ulAddress, tBoolean bSync)
{
tBoolean bRetcode;
unsigned char pucBuffer[3];
//
// Make sure the address passed is aligned correctly.
//
if(ulAddress & (W25X80A_BLOCK_SIZE - 1))
{
//
// Oops - it's not on a block boundary so fail the call.
//
return(false);
}
//
// Wait for the flash to be idle.
//
bRetcode = SSIFlashIdleWait(0);
//
// If the device is not idle, return an error.
//
if(!bRetcode)
{
return(bRetcode);
}
//
// Enable write operations.
//
bRetcode = SSIFlashWriteEnable();
//
// If write operations could not be enabled, return the error.
//
if(!bRetcode)
{
return(bRetcode);
}
//
// Now perform the instruction we need to erase the block.
//
pucBuffer[0] = (unsigned char)((ulAddress >> 16) & 0xFF);
pucBuffer[1] = (unsigned char)((ulAddress >> 8) & 0xFF);
pucBuffer[2] = (unsigned char)(ulAddress & 0xFF);
SSIFlashInstructionWrite(INSTR_BLOCK_ERASE, pucBuffer, 3);
SSIFlashInstructionEnd();
//
// Wait for the instruction to complete if the function is being called
// synchronously.
//
if(bSync)
{
bRetcode = SSIFlashIdleWait(MAX_BUSY_POLL_ERASE_BLOCK);
}
//
// Tell the caller how things went.
//
return(bRetcode);
}
//*****************************************************************************
//
//! Erases the entire serial flash device.
//!
//! \param bSync should be set to \b true if the function is to block until
//! the erase operation is complete or \b false to return immediately after
//! the operation is started.
//!
//! This function erases the entire serial flash device, returning all
//! bytes in the device to their erased value of 0xFF.
//!
//! The function may be synchronous (\e bSync set to \b true) or asynchronous
//! (\e bSync set to \b false). If asynchronous, the caller is responsible for
//! ensuring that no further serial flash operations are requested until the
//! erase operation has completed. The state of the device may be queried by
//! calling SSIFlashIsBusy().
//!
//! \note This operation will take between 6 and 10 seconds to complete. If the
//! \e bSync parameter is set to \b true, this function will, therefore, not
//! not return for a significant period of time.
//!
//! \return Returns \b true on success or \b false on failure.
//
//*****************************************************************************
tBoolean
SSIFlashChipErase(tBoolean bSync)
{
tBoolean bRetcode;
//
// Wait for the flash to be idle.
//
bRetcode = SSIFlashIdleWait(0);
//
// If the device is not idle, return an error.
//
if(!bRetcode)
{
return(bRetcode);
}
//
// Enable write operations.
//
bRetcode = SSIFlashWriteEnable();
//
// If write operations could not be enabled, return the error.
//
if(!bRetcode)
{
return(bRetcode);
}
//
// Now perform the instruction we need to erase the chip.
//
SSIFlashInstructionWrite(INSTR_CHIP_ERASE, (unsigned char *)0, 0);
SSIFlashInstructionEnd();
//
// Wait for the instruction to complete if the function is being called
// synchronously.
//
if(bSync)
{
bRetcode = SSIFlashIdleWait(MAX_BUSY_POLL_ERASE_CHIP);
}
//
// Tell the caller how things went.
//
return(bRetcode);
}
//*****************************************************************************
//
//! Reads a block of serial flash into a buffer.
//!
//! \param ulAddress is the serial flash address of the first byte to be read.
//! \param ulLength is the number of bytes of data to read.
//! \param pucDst is a pointer to storage for the data read.
//!
//! This function reads a contiguous block of data from a given address in the
//! serial flash device into a buffer supplied by the caller.
//!
//! \return Returns the number of bytes read.
//
//*****************************************************************************
unsigned long
SSIFlashRead(unsigned long ulAddress, unsigned long ulLength,
unsigned char *pucDst)
{
tBoolean bRetcode;
unsigned char pucBuffer[3];
//
// Wait for the flash to be idle.
//
bRetcode = SSIFlashIdleWait(0);
//
// If the device is not idle, return an error.
//
if(!bRetcode)
{
return(0);
}
//
// Send the read instruction and start address.
//
pucBuffer[0] = (unsigned char)((ulAddress >> 16) & 0xFF);
pucBuffer[1] = (unsigned char)((ulAddress >> 8) & 0xFF);
pucBuffer[2] = (unsigned char)(ulAddress & 0xFF);
SSIFlashInstructionWrite(INSTR_READ_DATA, pucBuffer, 3);
//
// Read back the data.
//
SSIFlashInstructionRead(pucDst, ulLength);
//
// Tell the flash device we have read everything we need.
//
SSIFlashInstructionEnd();
//
// Return the number of bytes read.
//
return(ulLength);
}
//*****************************************************************************
//
//! Writes a block of data to the serial flash device.
//!
//! \param ulAddress is the first serial flash address to be written.
//! \param ulLength is the number of bytes of data to write.
//! \param pucSrc is a pointer to the data which is to be written.
//!
//! This function writes a block of data into the serial flash device at the
//! given address. It is assumed that the area to be written has previously
//! been erased.
//!
//! \return Returns the number of bytes written.
//
//*****************************************************************************
unsigned long
SSIFlashWrite(unsigned long ulAddress, unsigned long ulLength,
unsigned char *pucSrc)
{
tBoolean bRetcode;
unsigned long ulLeft, ulStart, ulPageLeft;
unsigned char pucBuffer[3];
unsigned char *pucStart;
//
// Wait for the flash to be idle.
//
bRetcode = SSIFlashIdleWait(MAX_BUSY_POLL_IDLE);
//
// If the device is not idle, return an error.
//
if(!bRetcode)
{
return(bRetcode);
}
//
// Get set up to start writing pages.
//
ulStart = ulAddress;
ulLeft = ulLength;
pucStart = pucSrc;
//
// Keep writing pages until we have nothing left to write.
//
while(ulLeft)
{
//
// How many bytes do we have to write in the current page?
//
ulPageLeft = W25X80A_PAGE_SIZE - (ulStart & (W25X80A_PAGE_SIZE - 1));
//
// How many bytes can we write in the current page?
//
ulPageLeft = (ulPageLeft >= ulLeft) ? ulLeft : ulPageLeft;
//
// Enable write operations.
//
if(!SSIFlashWriteEnable())
{
//
// If we can't write enable the device, exit, telling the caller
// how many bytes we've already written.
//
return(ulLength - ulLeft);
}
//
// Write a chunk of data into one flash page.
//
pucBuffer[0] = (unsigned char)((ulStart >> 16) & 0xFF);
pucBuffer[1] = (unsigned char)((ulStart >> 8) & 0xFF);
pucBuffer[2] = (unsigned char)(ulStart & 0xFF);
SSIFlashInstructionWrite(INSTR_PAGE_PROGRAM, pucBuffer, 3);
SSIFlashInstructionDataWrite(pucStart, ulPageLeft);
SSIFlashInstructionEnd();
//
// Wait for the page write to complete.
//
bRetcode = SSIFlashIdleWait(MAX_BUSY_POLL_PROGRAM_PAGE);
if(!bRetcode)
{
//
// If we timed out waiting for the program operation to finish,
// exit, telling the caller how many bytes we've already written.
//
return(ulLength - ulLeft);
}
//
// Update our pointers and counters for the next page.
//
ulLeft -= ulPageLeft;
ulStart += ulPageLeft;
pucStart += ulPageLeft;
}
//
// If we get here, all is well and we wrote all the required data.
//
return(ulLength);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -