| /******************************************************************************* |
| Copyright (C) Marvell International Ltd. and its affiliates |
| |
| This software file (the "File") is owned and distributed by Marvell |
| International Ltd. and/or its affiliates ("Marvell") under the following |
| alternative licensing terms. Once you have made an election to distribute the |
| File under one of the following license alternatives, please (i) delete this |
| introductory statement regarding license alternatives, (ii) delete the two |
| license alternatives that you have not elected to use and (iii) preserve the |
| Marvell copyright notice above. |
| |
| ******************************************************************************** |
| Marvell Commercial License Option |
| |
| If you received this File from Marvell and you have entered into a commercial |
| license agreement (a "Commercial License") with Marvell, the File is licensed |
| to you under the terms of the applicable Commercial License. |
| |
| ******************************************************************************** |
| Marvell GPL License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File in accordance with the terms and conditions of the General |
| Public License Version 2, June 1991 (the "GPL License"), a copy of which is |
| available along with the File in the license.txt file or by writing to the Free |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or |
| on the worldwide web at http://www.gnu.org/licenses/gpl.txt. |
| |
| THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY |
| DISCLAIMED. The GPL License provides additional details about this warranty |
| disclaimer. |
| ******************************************************************************** |
| Marvell BSD License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File under the following licensing terms. |
| Redistribution and use in source and binary forms, with or without modification, |
| are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright notice, |
| this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| |
| * Neither the name of Marvell nor the names of its contributors may be |
| used to endorse or promote products derived from this software without |
| specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| *******************************************************************************/ |
| #include "mflash/mvSMFlash.h" |
| #include "mflash/mvSMFlashSpec.h" |
| #include "mflash/mvMFlash.h" |
| #include "mflash/mvMFlashSpec.h" |
| #include "spi/mvSpi.h" |
| #include "spi/mvSpiCmnd.h" |
| #include "ctrlEnv/mvCtrlEnvLib.h" |
| |
| /*#define MV_DEBUG*/ |
| #ifdef MV_DEBUG |
| #define DB(x) x |
| #else |
| #define DB(x) |
| #endif |
| |
| /* Static Functions */ |
| static MV_STATUS mvSingleByteCmnd (MV_U8 opcode); |
| static MV_STATUS mvSingleByteRead (MV_U8 opcode, MV_U8* pData); |
| static MV_STATUS mvSingleByteWrite (MV_U8 opcode, MV_U8 data); |
| static MV_STATUS mvWriteEnable (MV_VOID); |
| static MV_STATUS mvStatusRegGet (MV_U8* pStatus); |
| static MV_STATUS mvWaitOnWipClear (MV_VOID); |
| |
| /******************************************************************************* |
| * mvSingleByteCmnd - Issue an 8bit commmand |
| * |
| * DESCRIPTION: |
| * serialize an 8bit command without any data |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvSingleByteCmnd(MV_U8 opcode) |
| { |
| MV_U8 cmd[1]; |
| cmd[0] = opcode; |
| return mvSpiWriteThenRead(cmd, 1, NULL, 0,0); |
| } |
| |
| /******************************************************************************* |
| * mvSingleByteCmnd - Issue an 8bit Read |
| * |
| * DESCRIPTION: |
| * serialize an 8bit command and read 8bits of data |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvSingleByteRead(MV_U8 opcode, MV_U8* pData) |
| { |
| MV_U8 cmd[1]; |
| cmd[0] = opcode; |
| return mvSpiWriteThenRead(cmd, 1, pData, 1,0); |
| } |
| |
| /******************************************************************************* |
| * mvSingleByteWrite - Issue an 8bit Write |
| * |
| * DESCRIPTION: |
| * serialize an 8bit command and 8bits of data |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvSingleByteWrite(MV_U8 opcode, MV_U8 data) |
| { |
| return mvSpiWriteThenWrite(&opcode, 1, &data, 1); |
| } |
| |
| /******************************************************************************* |
| * mvWriteEnable - Perform the write enable sequence |
| * |
| * DESCRIPTION: |
| * Writa enable sequence needed before program and erase commands |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvWriteEnable(MV_VOID) |
| { |
| return mvSingleByteCmnd(MV_SMFLASH_WREN_CMND_OPCD); |
| } |
| |
| /******************************************************************************* |
| * mvStatusRegGet - Retreiv the value of the status register |
| * |
| * DESCRIPTION: |
| * perform the RDSR sequence to get the 8bit status register |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvStatusRegGet(MV_U8* pStatus) |
| { |
| return mvSingleByteRead(MV_SMFLASH_RDSR_CMND_OPCD, pStatus); |
| } |
| |
| /******************************************************************************* |
| * mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared |
| * |
| * DESCRIPTION: |
| * Block waiting for the WIP (write in progress) to be cleared |
| * |
| ********************************************************************************/ |
| static MV_STATUS mvWaitOnWipClear(MV_VOID) |
| { |
| MV_STATUS ret; |
| MV_U32 i; |
| MV_U8 status; |
| |
| for (i=0; i<MV_MFLASH_MAX_PRG_LOOP; i++) |
| { |
| /* Read the status register */ |
| if ((ret = mvStatusRegGet(&status)) != MV_OK) |
| return ret; |
| |
| /* check if write in progress bit was cleared by h/w */ |
| if ((status & MV_SMFLASH_STATUS_REG_WIP_MASK) == 0) |
| return MV_OK; |
| } |
| |
| DB(mvOsPrintf("%s WARNING: Wait Timeout!\n", __FUNCTION__);) |
| return MV_TIMEOUT; |
| } |
| |
| /* |
| ##################################################################################### |
| ##################################################################################### |
| */ |
| |
| /******************************************************************************* |
| * mvSMFlashInit - Initialize the Marvell serial flash device |
| * |
| * DESCRIPTION: |
| * Perform the neccessary initialization and configuration |
| * |
| * INPUT: |
| * flinfo: Flash information structure |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashInit (MV_MFLASH_INFO *pFlash) |
| { |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashChipErase - Erase the whole chip |
| * |
| * DESCRIPTION: |
| * Perform the chip erase sequence. To set both the Main and information |
| * regions to logic ones. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashChipErase (MV_MFLASH_INFO *pFlash) |
| { |
| MV_STATUS ret = MV_OK; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| if ((ret = mvSingleByteCmnd(MV_SMFLASH_CHIP_ERASE_CMND_OPCD)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return ret; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashMainErase - Erase the Main flash region only |
| * |
| * DESCRIPTION: |
| * Erase the main flash region to ones. Information region will not be |
| * affected. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashMainErase (MV_MFLASH_INFO *pFlash) |
| { |
| MV_STATUS ret = MV_OK; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| if ((ret = mvSingleByteCmnd(MV_SMFLASH_MAIN_ERASE_CMND_OPCD)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return ret; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashInfErase - Erase the whole information region only |
| * |
| * DESCRIPTION: |
| * Erase the whole information region without affecting the Main region. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashInfErase (MV_MFLASH_INFO *pFlash) |
| { |
| MV_STATUS ret = MV_OK; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| if ((ret = mvSingleByteCmnd(MV_SMFLASH_IPG_ERASE_CMND_OPCD)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return ret; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashSecErase - Erase a single sector of the Main region |
| * |
| * DESCRIPTION: |
| * Perform the sequence to erase a Main region sector |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * secNumber: sector number to erase. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashSecErase (MV_MFLASH_INFO *pFlash, MV_U32 secAddr) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_PAGE_ERASE_CMND_LEN]; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| cmd[0] = MV_SMFLASH_PAGE_ERASE_CMND_OPCD; |
| cmd[1] = ((secAddr >> 16) & 0xFF); /* address bits 16 - 23 */ |
| cmd[2] = ((secAddr >> 8) & 0xFF); /* address bits 8 - 15 */ |
| cmd[3] = (secAddr & 0xFF); /* address bits 0 - 7 */ |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| if ((ret = mvSpiWriteThenRead(cmd, MV_SMFLASH_PAGE_ERASE_CMND_LEN, NULL, 0, 0)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return ret; |
| } |
| |
| |
| |
| /******************************************************************************* |
| * mvSMFlash64bWr - Program 64 bytes of Data alligned to 64 boundaries |
| * |
| * DESCRIPTION: |
| * Program to main region 64 bytes of Data alligned to 64 boundaries |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address to start the programming from (alligned to 64 bytes) |
| * pBlock: pointer to the 64 bytes to program |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlash64bWr(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_PRGRM_CMND_LEN]; |
| |
| /* Check for null pointer */ |
| #ifndef CONFIG_MARVELL |
| if(NULL == pBlock) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| #endif |
| |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check allignment */ |
| if (offset & MV_SMFLASH_PAGE_ALLIGN_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Allignment error!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_PRGRM_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenWrite(cmd, MV_SMFLASH_PRGRM_CMND_LEN, pBlock, MV_SMFLASH_PAGE_SIZE)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlash64bWrVerify - Program and verify 64 bytes of Data alligned to |
| * 64 bytes boundaries |
| * |
| * DESCRIPTION: |
| * Program and verifyto main region 64 bytes of Data alligned to 64 |
| * bytes boundaries |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address to start the programming from (alligned to 64 bytes) |
| * pBlock: pointer to the 64 bytes to program |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlash64bWrVerify(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_PRGRM_CMP_CMND_LEN]; |
| MV_U8 status; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pBlock == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check allignment */ |
| if (offset & MV_SMFLASH_PAGE_ALLIGN_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Allignment error!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_PRGRM_CMP_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenWrite(cmd, MV_SMFLASH_PRGRM_CMP_CMND_LEN, pBlock, MV_SMFLASH_PAGE_SIZE)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| /* Read the status register */ |
| if ((ret = mvStatusRegGet(&status)) != MV_OK) |
| return ret; |
| |
| /* check if result of the compare operartion */ |
| if (status & MV_SMFLASH_STATUS_REG_CMP_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Compare after write error!\n", __FUNCTION__);) |
| return MV_FAIL; |
| } |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlash64bInfWr - Information region program 64 bytes of Data alligned |
| * to 64 bytes boundaries |
| * |
| * DESCRIPTION: |
| * Program to information region 64 bytes of Data alligned to 64 boundaries |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address to start the programming from (alligned to 64 bytes) |
| * pBlock: pointer to the 64 bytes to program |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlash64bInfWr(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_IPRGRM_CMND_LEN]; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pBlock == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check allignment */ |
| if (offset & MV_SMFLASH_PAGE_ALLIGN_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Allignment error!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_IPRGRM_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenWrite(cmd, MV_SMFLASH_IPRGRM_CMND_LEN, pBlock, MV_SMFLASH_PAGE_SIZE)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlash64bInfWrVerify - Program and verify 64 bytes of Data ti the |
| * information region alligned to 64 boundaries |
| * |
| * DESCRIPTION: |
| * Program and then verify to the information region 64 bytes of Data |
| * alligned to 64 boundaries |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address to start the programming from (alligned to 64 bytes) |
| * pBlock: pointer to the 64 bytes to program |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlash64bInfWrVerify(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_IPRGRM_CMP_CMND_LEN]; |
| MV_U8 status; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pBlock == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check allignment */ |
| if (offset & MV_SMFLASH_PAGE_ALLIGN_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Allignment error!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_IPRGRM_CMP_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenWrite(cmd, MV_SMFLASH_IPRGRM_CMP_CMND_LEN, pBlock, MV_SMFLASH_PAGE_SIZE)) != MV_OK) |
| return ret; |
| |
| /* wait for the write in progress bit to be cleared in the status register */ |
| if ((ret = mvWaitOnWipClear()) != MV_OK) |
| return ret; |
| |
| /* Read the status register */ |
| if ((ret = mvStatusRegGet(&status)) != MV_OK) |
| return ret; |
| |
| /* check if result of the compare operartion */ |
| if (status & MV_SMFLASH_STATUS_REG_CMP_MASK) |
| { |
| DB(mvOsPrintf("%s WARNING: Compare after information region write error!\n", __FUNCTION__);) |
| return MV_FAIL; |
| } |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashBlockRd - Read from the main region into a buffer |
| * |
| * DESCRIPTION: |
| * Issue the main region read sequence. Size and offset are not limited |
| * except to the size of the flash. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address in the main region to start the reading from. |
| * blockSize: size of the buffer to be read |
| * pBlock: pointer to the buffer to hold the data read from the flash |
| * |
| * OUTPUT: |
| * pBlock: pointer to the buffer holding the data from the flash |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashBlockRd(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U32 blockSize, |
| MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_READ_CMND_LEN]; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pBlock == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check that requested data is in the region */ |
| if ((offset + blockSize) > (pFlash->sectorNumber * pFlash->sectorSize)) |
| { |
| DB(mvOsPrintf("%s WARNING: Read exceeds flash size!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_READ_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenRead(cmd, MV_SMFLASH_READ_CMND_LEN, pBlock, blockSize, 0)) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashBlockInfRd - Read from the information region into a buffer |
| * |
| * DESCRIPTION: |
| * Issue the information region read sequence. Size and offset are not |
| * limited except to the size of the information region. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * offset: address in the information region to start the reading from. |
| * blockSize: size of the buffer to be read |
| * pBlock: pointer to the buffer to hold the data read from the flash |
| * |
| * OUTPUT: |
| * pBlock: pointer to the buffer holding the data from the flash |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashBlockInfRd(MV_MFLASH_INFO *pFlash, MV_U32 offset, MV_U32 blockSize, |
| MV_U8 *pBlock) |
| { |
| MV_STATUS ret; |
| MV_U8 cmd[MV_SMFLASH_IREAD_CMND_LEN]; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pBlock == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* check that requested data is in the region */ |
| if ((offset + blockSize) > pFlash->infoSize) |
| { |
| DB(mvOsPrintf("%s WARNING: Read exceeds information region size!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* encode the command to send */ |
| cmd[0] = MV_SMFLASH_IREAD_CMND_OPCD; |
| cmd[1] = ((offset >> 16) & 0xFF); |
| cmd[2] = ((offset >> 8) & 0xFF); |
| cmd[3] = (offset & 0xFF); |
| |
| /* Perform the write enable sequence */ |
| if ((ret = mvWriteEnable()) != MV_OK) |
| return ret; |
| |
| /* serialize the command and then followed by the data to program */ |
| if ((ret = mvSpiWriteThenRead(cmd, MV_SMFLASH_IREAD_CMND_LEN, pBlock, blockSize, 0)) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashReadConfig3 - Read the value of the configuration register |
| * |
| * DESCRIPTION: |
| * Read the value of the configuration register #3 |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * configReg: pointer to the 8bit variable to read in the config register |
| * |
| * OUTPUT: |
| * configReg: pointer to the 8bit varable holding the config register |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashReadConfig3(MV_MFLASH_INFO *pFlash, MV_U8 * pConfigReg) |
| { |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pConfigReg == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return mvSingleByteRead(MV_SMFLASH_READ_CFG_3_CMND_OPCD, pConfigReg); |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashReadConfig4 - Read the value of the configuration register |
| * |
| * DESCRIPTION: |
| * Read the value of the configuration register #4 |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * configReg: pointer to the 8bit variable to read in the config register |
| * |
| * OUTPUT: |
| * configReg: pointer to the 8bit varable holding the config register |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashReadConfig4(MV_MFLASH_INFO *pFlash, MV_U8 * pConfigReg) |
| { |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pConfigReg == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return mvSingleByteRead(MV_SMFLASH_READ_CFG_4_CMND_OPCD, pConfigReg); |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashSetConfig3 - Set the value of the configuration register |
| * |
| * DESCRIPTION: |
| * Set the value of the configuration register #3 |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * configReg: 8bit variable to be written to the config register |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashSetConfig3(MV_MFLASH_INFO *pFlash, MV_U8 configReg) |
| { |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return mvSingleByteWrite(MV_SMFLASH_SET_CFG_3_CMND_OPCD, configReg); |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashSetConfig4 - Set the value of the configuration register |
| * |
| * DESCRIPTION: |
| * Set the value of the configuration register #4 |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * configReg: 8bit variable to be written to the config register |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashSetConfig4(MV_MFLASH_INFO *pFlash, MV_U8 configReg) |
| { |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return mvSingleByteWrite(MV_SMFLASH_SET_CFG_4_CMND_OPCD, configReg); |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashWriteProtectSet - Write protect the whole flash device |
| * |
| * DESCRIPTION: |
| * Enable/Disable the write protection on the whole flash device. |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * wp: enable/disable (MV_TRUE/MV_FALSE) write protection |
| * |
| * OUTPUT: |
| * None |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashWriteProtectSet(MV_MFLASH_INFO *pFlash, MV_BOOL wp) |
| { |
| MV_STATUS ret; |
| MV_U8 reg; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* Read the serial configuration register #4 */ |
| if ((ret = mvSMFlashReadConfig4(pFlash, ®)) != MV_OK) |
| return ret; |
| |
| /* set the WP bit according to the wp input */ |
| if (wp) |
| reg &= ~MV_SMFLASH_SRL_CFG4_WP_MASK; |
| else |
| reg |= MV_SMFLASH_SRL_CFG4_WP_MASK; |
| |
| /* write back the serial configuration register #4 */ |
| if ((ret = mvSMFlashSetConfig4(pFlash, reg)) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * mvSMFlashSectorSizeSet - Set the sector size |
| * |
| * DESCRIPTION: |
| * Set the sector size (4K or 32K) |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * secSize: requested sector size |
| * |
| * OUTPUT: |
| * None |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashSectorSizeSet(MV_MFLASH_INFO *pFlash, MV_U32 secSize) |
| { |
| MV_STATUS ret; |
| MV_U8 reg; |
| |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| /* Read the serial configuration register #4 */ |
| if ((ret = mvSMFlashReadConfig4(pFlash, ®)) != MV_OK) |
| return ret; |
| |
| /* set the PAGE4K bit according to the secSize input */ |
| switch (secSize) |
| { |
| case MV_MFLASH_SECTOR_SIZE_BIG: |
| reg &= ~MV_SMFLASH_SRL_CFG4_PG_SIZE_MASK; /* 32K sectors */ |
| break; |
| |
| case MV_MFLASH_SECTOR_SIZE_SMALL: |
| reg |= MV_SMFLASH_SRL_CFG4_PG_SIZE_MASK; /* 4K sectors */ |
| break; |
| |
| default: |
| DB(mvOsPrintf("%s WARNING: Invalid parameter sector size!\n", __FUNCTION__);) |
| return MV_BAD_PARAM; |
| } |
| |
| /* write back the serial configuration register #4 */ |
| if ((ret = mvSMFlashSetConfig4(pFlash, reg)) != MV_OK) |
| return ret; |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashShutdownSet - Put the flash device in power save mode |
| * |
| * DESCRIPTION: |
| * Put the flash device in power save mode |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * |
| * OUTPUT: |
| * None |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashShutdownSet(MV_MFLASH_INFO *pFlash) |
| { |
| /* Check for null pointer */ |
| if (pFlash == NULL) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| return mvSingleByteCmnd(MV_SMFLASH_SHUTDOWN_CMND_OPCD); |
| } |
| |
| /******************************************************************************* |
| * mvSMFlashIdGet - Retreive the Manufacturer ID and Device ID |
| * |
| * DESCRIPTION: |
| * Read from the flash device the |
| * |
| * INPUT: |
| * pFlash: Flash information structure |
| * |
| * OUTPUT: |
| * None |
| * |
| * RETURN: |
| * Success or Error code. |
| * |
| * |
| *******************************************************************************/ |
| MV_STATUS mvSMFlashIdGet(MV_MFLASH_INFO *pFlash, MV_U32 * pManfCode, MV_U16 * pDevCode) |
| { |
| MV_STATUS ret = MV_OK; |
| MV_U8 cmd[MV_SMFLASH_RDID_CMND_LEN]; |
| MV_U8 id[MV_SMFLASH_RDID_RPLY_LEN]; |
| |
| /* Check for null pointer */ |
| if ((pFlash == NULL) || (pManfCode == NULL) || (pDevCode == NULL)) |
| { |
| mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__); |
| return MV_BAD_PARAM; |
| } |
| |
| cmd[0] = MV_SMFLASH_RDID_CMND_OPCD; |
| |
| if ((ret = mvSpiWriteThenRead(cmd, MV_SMFLASH_RDID_CMND_LEN, id, MV_SMFLASH_RDID_RPLY_LEN, 0)) != MV_OK) |
| return ret; |
| |
| *pManfCode = ((id[0] << 24) | (id[1] << 16) | (id[2] << 8) | (id[3])); |
| *pDevCode = ((id[4] << 8) | (id[5])); |
| |
| return ret; |
| } |
| |
| |
| |