对比新文件 |
| | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \file |
| | | * |
| | | * \brief PAL Flash driver. |
| | | * |
| | | * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. |
| | | * |
| | | * Copyright (c) 2019-2020 Packetcraft, Inc. |
| | | * |
| | | * Licensed under the Apache License, Version 2.0 (the "License"); |
| | | * you may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at |
| | | * |
| | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | |
| | | #include <string.h> |
| | | #include "pal_flash.h" |
| | | #include "mk_flash.h" |
| | | |
| | | /************************************************************************************************** |
| | | Macros |
| | | **************************************************************************************************/ |
| | | // The size of flash space available to users is 8K |
| | | #define MK8000_USER_TOTAL_SIZE 0x2000 |
| | | // The starting address is 0x0407E000, 126th sector |
| | | #define MK8000_USER_START_ADDR 0x0407E000 |
| | | // The end address is 0x0407FFFF |
| | | #define MK8000_USER_END_ADDR (MK8000_USER_START_ADDR + MK8000_USER_TOTAL_SIZE - 1) |
| | | |
| | | /*! Flash block size. */ |
| | | #define PAL_FLASH_SECTOR4K 1 |
| | | // #define PAL_FLASH_SECTOR64K 16 |
| | | |
| | | #define PAL_FLASH_SECTOR4K_SIZE FLASH_SECTOR_SIZE |
| | | // #define PAL_FLASH_SECTOR64K_SIZE 0x10000 |
| | | |
| | | /*! Flash Total size. */ |
| | | #define PAL_FLASH_TOTAL_SIZE MK8000_USER_TOTAL_SIZE |
| | | |
| | | /*! Flash internal cache buffer size. Note: should be at least 2. */ |
| | | #define PAL_FLASH_CACHE_BUF_SIZE 11 |
| | | |
| | | /*! Flash word size. */ |
| | | #define PAL_FLASH_WORD_SIZE 4 |
| | | |
| | | /*! Aligns a value to word size. */ |
| | | #define PAL_FLASH_WORD_ALIGN(value) (((value) + (PAL_FLASH_WORD_SIZE - 1)) & ~(PAL_FLASH_WORD_SIZE - 1)) |
| | | /*! Validates if a value is aligned to word. */ |
| | | #define PAL_FLASH_IS_WORD_ALIGNED(value) (((uint32_t)(value) & (PAL_FLASH_WORD_SIZE - 1)) == 0) |
| | | |
| | | /*! QSPI flash commands. */ |
| | | #define QSPI_STD_CMD_WRSR 0x01 |
| | | #define QSPI_STD_CMD_RSTEN 0x66 |
| | | #define QSPI_STD_CMD_RST 0x99 |
| | | |
| | | #ifdef DEBUG |
| | | |
| | | /*! \brief Parameter check. */ |
| | | #define PAL_FLASH_PARAM_CHECK(expr) \ |
| | | { \ |
| | | if (!(expr)) \ |
| | | { \ |
| | | palFlashCb.state = PAL_FLASH_STATE_ERROR; \ |
| | | return; \ |
| | | } \ |
| | | } |
| | | |
| | | #else |
| | | |
| | | /*! \brief Parameter check (disabled). */ |
| | | #define PAL_FLASH_PARAM_CHECK(expr) |
| | | |
| | | #endif |
| | | |
| | | /************************************************************************************************** |
| | | Local Variables |
| | | **************************************************************************************************/ |
| | | |
| | | /*! flash cache buffer. */ |
| | | static uint32_t palFlashCacheBuf[PAL_FLASH_CACHE_BUF_SIZE]; |
| | | static enum FLASH_DEV_T MK8000_FLASH_ID = FLASH_ID0; |
| | | static enum FLASH_DEV_T flash_id = FLASH_MAX_NUM; |
| | | |
| | | /*! \brief Control block. */ |
| | | static struct |
| | | { |
| | | PalFlashState_t state; /*!< State. */ |
| | | uint32_t writeAddr; /*!< Write address. */ |
| | | } palFlashCb; |
| | | |
| | | /************************************************************************************************** |
| | | Global Functions |
| | | **************************************************************************************************/ |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Initialize flash. |
| | | * |
| | | * \param[in] actCback Callback function. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashInit(PalFlashCback_t actCback) |
| | | { |
| | | (void)palFlashCacheBuf; |
| | | if (DRV_OK == flash_open(MK8000_FLASH_ID, NULL)) |
| | | { |
| | | flash_id = FLASH_ID0; |
| | | } |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief De-initialize flash. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashDeInit(void) |
| | | { |
| | | flash_close(flash_id); |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Reads data from flash storage. |
| | | * |
| | | * \param[in] pBuf Pointer to memory buffer where data will be stored. |
| | | * \param[in] size Data size in bytes to be read. |
| | | * \param[in] srcAddr Word aligned address from where data is read. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashRead(void *pBuf, uint32_t size, uint32_t srcAddr) |
| | | { |
| | | uint32_t realAddr; |
| | | memset(pBuf, 0xFF, size); |
| | | realAddr = MK8000_USER_START_ADDR + srcAddr; |
| | | flash_read(flash_id, realAddr, (uint8_t *)pBuf, size); |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Writes data to flash storage. |
| | | * |
| | | * \param[in] pBuf Pointer to memory buffer from where data will be written. |
| | | * \param[in] size Data size in bytes to be written. |
| | | * \param[in] dstAddr Word aligned address to write data. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashWrite(const uint8_t *pBuf, uint32_t size, uint32_t dstAddr) |
| | | { |
| | | #if FLASH_WRITE_EN |
| | | uint32_t realAddr; |
| | | realAddr = MK8000_USER_START_ADDR + dstAddr; |
| | | flash_write_nbytes(flash_id, realAddr, pBuf, size); |
| | | #endif |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Erase sector. |
| | | * |
| | | * \param[in] numOfSectors Number of sectors to be erased. |
| | | * \param[in] startAddr Word aligned address. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashEraseSector(uint32_t numOfSectors, uint32_t startAddr) |
| | | { |
| | | #if FLASH_WRITE_EN |
| | | uint32_t realAddr; |
| | | realAddr = MK8000_USER_START_ADDR + startAddr; |
| | | if (PAL_FLASH_IS_WORD_ALIGNED(realAddr) && (numOfSectors > 0) && (numOfSectors <= (PAL_FLASH_TOTAL_SIZE / PAL_FLASH_SECTOR4K_SIZE))) |
| | | { |
| | | uint32_t sector_idx = (realAddr - FLASH_BASE) / PAL_FLASH_SECTOR4K_SIZE; |
| | | if ((sector_idx + numOfSectors) <= (FLASH_SIZE / PAL_FLASH_SECTOR4K_SIZE)) |
| | | { |
| | | for (uint32_t i = 0; i < numOfSectors; i++, sector_idx++) |
| | | { |
| | | flash_sector_erase(flash_id, sector_idx); |
| | | } |
| | | } |
| | | } |
| | | #endif |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Erase chip. It is not recommended to use since it takes up to 240s. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | void PalFlashEraseChip(void) |
| | | { |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Get total size of NVM storage. |
| | | * |
| | | * \return Total size. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | uint32_t PalNvmGetTotalSize(void) |
| | | { |
| | | return PAL_FLASH_TOTAL_SIZE; |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Get sector size of NVM storage. |
| | | * |
| | | * \return Sector size. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | uint32_t PalNvmGetSectorSize(void) |
| | | { |
| | | return PAL_FLASH_SECTOR4K_SIZE; |
| | | } |
| | | |
| | | /*************************************************************************************************/ |
| | | /*! |
| | | * \brief Get flash state. |
| | | * |
| | | * \return flash state. |
| | | */ |
| | | /*************************************************************************************************/ |
| | | PalFlashState_t PalFlashGetState(void) |
| | | { |
| | | return palFlashCb.state; |
| | | } |