aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c')
-rwxr-xr-xplatform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c878
1 files changed, 439 insertions, 439 deletions
diff --git a/platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c b/platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c
index 29b7650219..f2c9e4ede3 100755
--- a/platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c
+++ b/platform/ext/target/nxp/common/CMSIS_Driver/Driver_Flash.c
@@ -1,439 +1,439 @@
-/*
- * Copyright (c) 2013-2018 ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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
- *
- * 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.
- *
- * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
- * Copyright 2016-2019 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include "Driver_Flash.h"
-#include "platform_base_address.h"
-#include "flash_layout.h"
-#include "fsl_iap.h"
-
-#ifndef ARG_UNUSED
-#define ARG_UNUSED(arg) ((void)arg)
-#endif
-
-/* Below CMDs apply to both C040HDATFC and C040HDFC flash */
-#define FLASH_CMD_INIT 0
-#define FLASH_CMD_READ_SINGLE_WORD 3
-
-/* INT_STATUS - Interrupt status bits - taken from LPC5588_cm33_core0.h */
-
-#define FLASH_INT_STATUS_OVL_MASK (0x10U)
-
-/* Alignment macros - taken from bootloader_common.h */
-#ifndef ALIGN_DOWN
-#define ALIGN_DOWN(x, a) ((x) & -(a))
-#endif
-
-/* Flash property defines */
-
-/* Mask the number of bits required to select the 32-bit data word (DATAW) from the flash line */
-#define FLASH_DATAW_IDX_MAX 3 /* Max DATAW index, 3 for a 128-bit flash line, 7 for 256-bit. */
-
-#define FLASH_READMODE_REG (FLASH->DATAW[0])
-#define FLASH_READMODE_ECC_MASK (0x4U)
-#define FLASH_READMODE_ECC_SHIFT (2U)
-#define FLASH_READMODE_ECC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_ECC_SHIFT)) & FLASH_READMODE_ECC_MASK)
-#define FLASH_READMODE_MARGIN_MASK (0xC00U)
-#define FLASH_READMODE_MARGIN_SHIFT (10U)
-#define FLASH_READMODE_MARGIN(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_MARGIN_SHIFT)) & FLASH_READMODE_MARGIN_MASK)
-#define FLASH_READMODE_DMACC_MASK (0x8000U)
-#define FLASH_READMODE_DMACC_SHIFT (15U)
-#define FLASH_READMODE_DMACC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_DMACC_SHIFT)) & FLASH_READMODE_DMACC_MASK)
-
-/* Driver version */
-#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
-
-/* ARM FLASH device structure */
-struct arm_flash_dev_t {
- const uint32_t memory_base; /*!< FLASH memory base address */
- ARM_FLASH_INFO *data; /*!< FLASH data */
- flash_config_t flashInstance; /*!< FLASH config*/
-};
-
-/* Flash Status */
-static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
-
-/* Driver Version */
-static const ARM_DRIVER_VERSION DriverVersion = {
- ARM_FLASH_API_VERSION,
- ARM_FLASH_DRV_VERSION
-};
-
-/* Driver Capabilities */
-static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
- 0, /* event_ready */
- 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
- 1 /* erase_chip */
-};
-
-static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
- .sector_info = NULL, /* Uniform sector layout */
- .sector_count = FLASH0_SIZE / FLASH0_PAGE_SIZE,
- .sector_size = FLASH0_PAGE_SIZE,
- .page_size = FLASH0_PAGE_SIZE,
- .program_unit = FLASH0_PAGE_SIZE,
- .erased_value = 0x00};
-
-static struct arm_flash_dev_t ARM_FLASH0_DEV = {
-#if (__DOMAIN_NS == 1)
- .memory_base = FLASH0_BASE_NS,
-#else
- .memory_base = FLASH0_BASE_S,
-#endif /* __DOMAIN_NS == 1 */
- .data = &(ARM_FLASH0_DEV_DATA)};
-
-struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
-
-/* Prototypes */
-
-/* Internal function Flash command sequence. Called by driver APIs only*/
-static status_t flash_command_sequence(flash_config_t *config);
-
-//static status_t FLASH_ReadInit(flash_config_t *config);
-static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
-static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData);
-
-static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
- uint32_t offset);
-static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
- uint32_t param);
-
-/* Functions */
-
-static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
-{
- return DriverVersion;
-}
-
-static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
-{
- return DriverCapabilities;
-}
-
-static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
-{
- ARG_UNUSED(cb_event);
- status_t status = kStatus_Success;
-
- /* Call initialization from Flash API */
- status = FLASH_Init(&FLASH0_DEV->flashInstance);
-
- if(status != kStatus_Success){
- return ARM_DRIVER_ERROR;
- }
-
-
- /* Disable Error Detection functionality */
- FLASH0_DEV->flashInstance.modeConfig.readSingleWord.readWithEccOff = 0x1;
-
-#if 0
- /* Initialization of Flash by means of its registers to be able read data*/
- if(FLASH_ReadInit(&FLASH0_DEV->flashInstance) != kStatus_Success){
- return ARM_DRIVER_ERROR;
- }
-#endif
-
- return ARM_DRIVER_OK;
-}
-
-static int32_t ARM_Flash_Uninitialize(void)
-{
- /* Nothing to be done */
- return ARM_DRIVER_OK;
-}
-
-static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
-{
- switch (state) {
- case ARM_POWER_FULL:
- /* Nothing to be done */
- return ARM_DRIVER_OK;
-
- case ARM_POWER_OFF:
- case ARM_POWER_LOW:
- default:
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
-}
-
-static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
-{
- static uint32_t status;
-
- /* Check Flash memory boundaries */
- status = is_range_valid(FLASH0_DEV, addr + cnt);
- if(status != kStatus_Success) {
- return ARM_DRIVER_ERROR_PARAMETER;
- }
-
- /* Read Data */
-#if 1
- if(cnt) {
- status = FLASH_ReadData(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
- if(status != kStatus_Success) {
- return ARM_DRIVER_ERROR;
- }
- }
-#else /* Bus fault when reading erased memory */
- (void)memcpy(data, (uint8_t *)addr, cnt);
-#endif
- return ARM_DRIVER_OK;
-}
-
-static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt)
-{
- static uint32_t status;
- uint32_t failedAddress, failedData;
-
- /* Check Flash memory boundaries */
- status = is_range_valid(FLASH0_DEV, addr);
- status |= is_write_aligned(FLASH0_DEV, addr);
- status |= is_write_aligned(FLASH0_DEV, cnt);
- if(status != kStatus_Success) {
- return ARM_DRIVER_ERROR_PARAMETER;
- }
-
- status = FLASH_Program(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
- if (status != kStatus_Success) {
- return ARM_DRIVER_ERROR;
- }
-
- status = FLASH_VerifyProgram(&FLASH0_DEV->flashInstance, addr, cnt, (const uint8_t *)data,
- &failedAddress, &failedData);
- if (status != kStatus_Success) {
- return ARM_DRIVER_ERROR;
- }
-
- return ARM_DRIVER_OK;
-}
-
-static int32_t ARM_Flash_EraseSector(uint32_t addr)
-{
- static uint32_t status;
-
- status = is_range_valid(FLASH0_DEV, addr);
- status |= is_write_aligned(FLASH0_DEV, addr);
- if(status != kStatus_Success) {
- return ARM_DRIVER_ERROR_PARAMETER;
- }
-
- status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH0_DEV->data->sector_size, kFLASH_ApiEraseKey);
- if (status != kStatus_Success) {
- return ARM_DRIVER_ERROR;
- }
-
- return ARM_DRIVER_OK;
-}
-
-static int32_t ARM_Flash_EraseChip(void)
-{
- static uint32_t status;
- uint32_t addr = FLASH0_DEV->memory_base;
-
- status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH_TOTAL_SIZE, kFLASH_ApiEraseKey);
- if (status != kStatus_Success)
- return ARM_DRIVER_ERROR;
-
- return ARM_DRIVER_OK;
-}
-
-static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
-{
- return FlashStatus;
-}
-
-static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
-{
- return FLASH0_DEV->data;
-}
-
-ARM_DRIVER_FLASH Driver_FLASH0 = {
- ARM_Flash_GetVersion,
- ARM_Flash_GetCapabilities,
- ARM_Flash_Initialize,
- ARM_Flash_Uninitialize,
- ARM_Flash_PowerControl,
- ARM_Flash_ReadData,
- ARM_Flash_ProgramData,
- ARM_Flash_EraseSector,
- ARM_Flash_EraseChip,
- ARM_Flash_GetStatus,
- ARM_Flash_GetInfo
-};
-
-#if 0
-static status_t FLASH_ReadInit(flash_config_t *config)
-{
- status_t status = kStatus_Fail;
-
- if (config == NULL)
- {
- return kStatus_FLASH_InvalidArgument;
- }
-
- /* config->PFlashTotalSize was initialized to 0xA0000 (640kB) by FLASH API.
- This value needs to be changed to 0x98000 (608kB)*/
- config->PFlashTotalSize = FLASH_TOTAL_SIZE;
-
- /* Immediately after leaving reset mode, an initialization phase takes place,
- where some memory locations are read, and corresponding volatile locations
- are initialized depending on the value just read. */
- FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
- FLASH->CMD = FLASH_CMD_INIT;
- status = flash_command_sequence(config);
-
- if (kStatus_FLASH_Success != status)
- {
- return status;
- }
-
- return kStatus_FLASH_Success;
-}
-#endif
-
-static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
-{
- status_t status = kStatus_Fail;
-
- uint32_t readbackData[FLASH_DATAW_IDX_MAX + 1];
- while (lengthInBytes)
- {
- uint32_t alignedStart = ALIGN_DOWN(start, kFLASH_AlignementUnitSingleWordRead);
- status = FLASH_ReadSingleWord(config, alignedStart, readbackData);
- if (status != kStatus_FLASH_Success)
- {
- break;
- }
- for (uint32_t i = 0; i < sizeof(readbackData); i++)
- {
- if ((alignedStart == start) && lengthInBytes)
- {
- *dest = *((uint8_t *)readbackData + i);
- dest++;
- start++;
- lengthInBytes--;
- }
- alignedStart++;
- }
- }
-
- return status;
-}
-
-static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData)
-{
- status_t status = kStatus_Fail;
- /* uint32_t byteSizes = sizeof(uint32_t) * (FLASH_DATAW_IDX_MAX + 1); */
-
- if (readbackData == NULL)
- {
- return kStatus_FLASH_InvalidArgument;
- }
-
- FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK |
- FLASH_INT_CLR_STATUS_DONE_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
-
- /* Set start address */
- FLASH->STARTA = start >> 4;
-
- /* ReadSingleWord notes:
- Flash contains one DMACC word per page. Such words are not readable through
- the read interface. DMACC words are managed internally by the controller in
- order to store a flag (all1), which can be used to verify whether a programming
- operation was prematurely terminated.
- DMACC words are all_0 for an erased page, all_1 for a programmed page */
-
- /* Set read modes */
- FLASH_READMODE_REG = FLASH_READMODE_ECC(config->modeConfig.readSingleWord.readWithEccOff) |
- FLASH_READMODE_MARGIN(config->modeConfig.readSingleWord.readMarginLevel) |
- FLASH_READMODE_DMACC(config->modeConfig.readSingleWord.readDmaccWord);
-
- /* Calling flash command sequence function to execute the command */
- FLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
- status = flash_command_sequence(config);
-
- if (kStatus_FLASH_Success == status)
- {
- for (uint32_t datawIndex = 0; datawIndex <= FLASH_DATAW_IDX_MAX; datawIndex++)
- {
- *readbackData++ = FLASH->DATAW[datawIndex];
- }
- }
-
- return status;
-}
-
-/* This function is used to perform the command write sequence to the flash. */
-static status_t flash_command_sequence(flash_config_t *config)
-{
- status_t status = kStatus_Fail;
- uint32_t registerValue;
-
- while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
- ;
-
- /* Check error bits */
- /* Get flash status register value */
- registerValue = FLASH->INT_STATUS;
-
- /* Checking access error */
- if (registerValue & FLASH_INT_STATUS_FAIL_MASK)
- {
- status = kStatus_FLASH_CommandFailure;
- }
- else if (registerValue & FLASH_INT_STATUS_ERR_MASK)
- {
- status = kStatus_FLASH_CommandNotSupported;
- }
- else if (registerValue & FLASH_INT_STATUS_ECC_ERR_MASK)
- {
- status = kStatus_FLASH_EccError;
- }
- else if (registerValue & FLASH_INT_STATUS_OVL_MASK)
- {
- status = kStatus_FLASH_RegulationLoss;
- }
- else
- {
- status = kStatus_FLASH_Success;
- }
-
- return status;
-}
-
-/* Check if the Flash memory boundaries are not violated. */
-static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
- uint32_t offset)
-{
-
- uint32_t flash_limit = FLASH_TOTAL_SIZE - 1;
-
- return (offset > flash_limit) ? (kStatus_Fail) : (kStatus_Success) ;
-}
-
-/* Check if the parameter is aligned to program_unit. */
-static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
- uint32_t param)
-{
- return ((param % flash_dev->data->program_unit) != 0) ? (kStatus_Fail) : (kStatus_Success);
-}
+/*
+ * Copyright (c) 2013-2018 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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
+ *
+ * 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.
+ *
+ * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "Driver_Flash.h"
+#include "platform_base_address.h"
+#include "flash_layout.h"
+#include "fsl_iap.h"
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg) ((void)arg)
+#endif
+
+/* Below CMDs apply to both C040HDATFC and C040HDFC flash */
+#define FLASH_CMD_INIT 0
+#define FLASH_CMD_READ_SINGLE_WORD 3
+
+/* INT_STATUS - Interrupt status bits - taken from LPC5588_cm33_core0.h */
+
+#define FLASH_INT_STATUS_OVL_MASK (0x10U)
+
+/* Alignment macros - taken from bootloader_common.h */
+#ifndef ALIGN_DOWN
+#define ALIGN_DOWN(x, a) ((x) & -(a))
+#endif
+
+/* Flash property defines */
+
+/* Mask the number of bits required to select the 32-bit data word (DATAW) from the flash line */
+#define FLASH_DATAW_IDX_MAX 3 /* Max DATAW index, 3 for a 128-bit flash line, 7 for 256-bit. */
+
+#define FLASH_READMODE_REG (FLASH->DATAW[0])
+#define FLASH_READMODE_ECC_MASK (0x4U)
+#define FLASH_READMODE_ECC_SHIFT (2U)
+#define FLASH_READMODE_ECC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_ECC_SHIFT)) & FLASH_READMODE_ECC_MASK)
+#define FLASH_READMODE_MARGIN_MASK (0xC00U)
+#define FLASH_READMODE_MARGIN_SHIFT (10U)
+#define FLASH_READMODE_MARGIN(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_MARGIN_SHIFT)) & FLASH_READMODE_MARGIN_MASK)
+#define FLASH_READMODE_DMACC_MASK (0x8000U)
+#define FLASH_READMODE_DMACC_SHIFT (15U)
+#define FLASH_READMODE_DMACC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_DMACC_SHIFT)) & FLASH_READMODE_DMACC_MASK)
+
+/* Driver version */
+#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
+
+/* ARM FLASH device structure */
+struct arm_flash_dev_t {
+ const uint32_t memory_base; /*!< FLASH memory base address */
+ ARM_FLASH_INFO *data; /*!< FLASH data */
+ flash_config_t flashInstance; /*!< FLASH config*/
+};
+
+/* Flash Status */
+static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
+
+/* Driver Version */
+static const ARM_DRIVER_VERSION DriverVersion = {
+ ARM_FLASH_API_VERSION,
+ ARM_FLASH_DRV_VERSION
+};
+
+/* Driver Capabilities */
+static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
+ 0, /* event_ready */
+ 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
+ 1 /* erase_chip */
+};
+
+static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
+ .sector_info = NULL, /* Uniform sector layout */
+ .sector_count = FLASH0_SIZE / FLASH0_PAGE_SIZE,
+ .sector_size = FLASH0_PAGE_SIZE,
+ .page_size = FLASH0_PAGE_SIZE,
+ .program_unit = FLASH0_PAGE_SIZE,
+ .erased_value = 0x00};
+
+static struct arm_flash_dev_t ARM_FLASH0_DEV = {
+#if (__DOMAIN_NS == 1)
+ .memory_base = FLASH0_BASE_NS,
+#else
+ .memory_base = FLASH0_BASE_S,
+#endif /* __DOMAIN_NS == 1 */
+ .data = &(ARM_FLASH0_DEV_DATA)};
+
+struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
+
+/* Prototypes */
+
+/* Internal function Flash command sequence. Called by driver APIs only*/
+static status_t flash_command_sequence(flash_config_t *config);
+
+//static status_t FLASH_ReadInit(flash_config_t *config);
+static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
+static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData);
+
+static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
+ uint32_t offset);
+static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
+ uint32_t param);
+
+/* Functions */
+
+static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
+{
+ return DriverVersion;
+}
+
+static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
+{
+ return DriverCapabilities;
+}
+
+static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
+{
+ ARG_UNUSED(cb_event);
+ status_t status = kStatus_Success;
+
+ /* Call initialization from Flash API */
+ status = FLASH_Init(&FLASH0_DEV->flashInstance);
+
+ if(status != kStatus_Success){
+ return ARM_DRIVER_ERROR;
+ }
+
+
+ /* Disable Error Detection functionality */
+ FLASH0_DEV->flashInstance.modeConfig.readSingleWord.readWithEccOff = 0x1;
+
+#if 0
+ /* Initialization of Flash by means of its registers to be able read data*/
+ if(FLASH_ReadInit(&FLASH0_DEV->flashInstance) != kStatus_Success){
+ return ARM_DRIVER_ERROR;
+ }
+#endif
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_Uninitialize(void)
+{
+ /* Nothing to be done */
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
+{
+ switch (state) {
+ case ARM_POWER_FULL:
+ /* Nothing to be done */
+ return ARM_DRIVER_OK;
+
+ case ARM_POWER_OFF:
+ case ARM_POWER_LOW:
+ default:
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+ }
+}
+
+static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
+{
+ static uint32_t status;
+
+ /* Check Flash memory boundaries */
+ status = is_range_valid(FLASH0_DEV, addr + cnt);
+ if(status != kStatus_Success) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ /* Read Data */
+#if 1
+ if(cnt) {
+ status = FLASH_ReadData(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
+ if(status != kStatus_Success) {
+ return ARM_DRIVER_ERROR;
+ }
+ }
+#else /* Bus fault when reading erased memory */
+ (void)memcpy(data, (uint8_t *)addr, cnt);
+#endif
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt)
+{
+ static uint32_t status;
+ uint32_t failedAddress, failedData;
+
+ /* Check Flash memory boundaries */
+ status = is_range_valid(FLASH0_DEV, addr);
+ status |= is_write_aligned(FLASH0_DEV, addr);
+ status |= is_write_aligned(FLASH0_DEV, cnt);
+ if(status != kStatus_Success) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ status = FLASH_Program(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
+ if (status != kStatus_Success) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ status = FLASH_VerifyProgram(&FLASH0_DEV->flashInstance, addr, cnt, (const uint8_t *)data,
+ &failedAddress, &failedData);
+ if (status != kStatus_Success) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseSector(uint32_t addr)
+{
+ static uint32_t status;
+
+ status = is_range_valid(FLASH0_DEV, addr);
+ status |= is_write_aligned(FLASH0_DEV, addr);
+ if(status != kStatus_Success) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH0_DEV->data->sector_size, kFLASH_ApiEraseKey);
+ if (status != kStatus_Success) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseChip(void)
+{
+ static uint32_t status;
+ uint32_t addr = FLASH0_DEV->memory_base;
+
+ status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH_TOTAL_SIZE, kFLASH_ApiEraseKey);
+ if (status != kStatus_Success)
+ return ARM_DRIVER_ERROR;
+
+ return ARM_DRIVER_OK;
+}
+
+static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
+{
+ return FlashStatus;
+}
+
+static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
+{
+ return FLASH0_DEV->data;
+}
+
+ARM_DRIVER_FLASH Driver_FLASH0 = {
+ ARM_Flash_GetVersion,
+ ARM_Flash_GetCapabilities,
+ ARM_Flash_Initialize,
+ ARM_Flash_Uninitialize,
+ ARM_Flash_PowerControl,
+ ARM_Flash_ReadData,
+ ARM_Flash_ProgramData,
+ ARM_Flash_EraseSector,
+ ARM_Flash_EraseChip,
+ ARM_Flash_GetStatus,
+ ARM_Flash_GetInfo
+};
+
+#if 0
+static status_t FLASH_ReadInit(flash_config_t *config)
+{
+ status_t status = kStatus_Fail;
+
+ if (config == NULL)
+ {
+ return kStatus_FLASH_InvalidArgument;
+ }
+
+ /* config->PFlashTotalSize was initialized to 0xA0000 (640kB) by FLASH API.
+ This value needs to be changed to 0x98000 (608kB)*/
+ config->PFlashTotalSize = FLASH_TOTAL_SIZE;
+
+ /* Immediately after leaving reset mode, an initialization phase takes place,
+ where some memory locations are read, and corresponding volatile locations
+ are initialized depending on the value just read. */
+ FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
+ FLASH->CMD = FLASH_CMD_INIT;
+ status = flash_command_sequence(config);
+
+ if (kStatus_FLASH_Success != status)
+ {
+ return status;
+ }
+
+ return kStatus_FLASH_Success;
+}
+#endif
+
+static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
+{
+ status_t status = kStatus_Fail;
+
+ uint32_t readbackData[FLASH_DATAW_IDX_MAX + 1];
+ while (lengthInBytes)
+ {
+ uint32_t alignedStart = ALIGN_DOWN(start, kFLASH_AlignementUnitSingleWordRead);
+ status = FLASH_ReadSingleWord(config, alignedStart, readbackData);
+ if (status != kStatus_FLASH_Success)
+ {
+ break;
+ }
+ for (uint32_t i = 0; i < sizeof(readbackData); i++)
+ {
+ if ((alignedStart == start) && lengthInBytes)
+ {
+ *dest = *((uint8_t *)readbackData + i);
+ dest++;
+ start++;
+ lengthInBytes--;
+ }
+ alignedStart++;
+ }
+ }
+
+ return status;
+}
+
+static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData)
+{
+ status_t status = kStatus_Fail;
+ /* uint32_t byteSizes = sizeof(uint32_t) * (FLASH_DATAW_IDX_MAX + 1); */
+
+ if (readbackData == NULL)
+ {
+ return kStatus_FLASH_InvalidArgument;
+ }
+
+ FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK |
+ FLASH_INT_CLR_STATUS_DONE_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
+
+ /* Set start address */
+ FLASH->STARTA = start >> 4;
+
+ /* ReadSingleWord notes:
+ Flash contains one DMACC word per page. Such words are not readable through
+ the read interface. DMACC words are managed internally by the controller in
+ order to store a flag (all1), which can be used to verify whether a programming
+ operation was prematurely terminated.
+ DMACC words are all_0 for an erased page, all_1 for a programmed page */
+
+ /* Set read modes */
+ FLASH_READMODE_REG = FLASH_READMODE_ECC(config->modeConfig.readSingleWord.readWithEccOff) |
+ FLASH_READMODE_MARGIN(config->modeConfig.readSingleWord.readMarginLevel) |
+ FLASH_READMODE_DMACC(config->modeConfig.readSingleWord.readDmaccWord);
+
+ /* Calling flash command sequence function to execute the command */
+ FLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
+ status = flash_command_sequence(config);
+
+ if (kStatus_FLASH_Success == status)
+ {
+ for (uint32_t datawIndex = 0; datawIndex <= FLASH_DATAW_IDX_MAX; datawIndex++)
+ {
+ *readbackData++ = FLASH->DATAW[datawIndex];
+ }
+ }
+
+ return status;
+}
+
+/* This function is used to perform the command write sequence to the flash. */
+static status_t flash_command_sequence(flash_config_t *config)
+{
+ status_t status = kStatus_Fail;
+ uint32_t registerValue;
+
+ while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
+ ;
+
+ /* Check error bits */
+ /* Get flash status register value */
+ registerValue = FLASH->INT_STATUS;
+
+ /* Checking access error */
+ if (registerValue & FLASH_INT_STATUS_FAIL_MASK)
+ {
+ status = kStatus_FLASH_CommandFailure;
+ }
+ else if (registerValue & FLASH_INT_STATUS_ERR_MASK)
+ {
+ status = kStatus_FLASH_CommandNotSupported;
+ }
+ else if (registerValue & FLASH_INT_STATUS_ECC_ERR_MASK)
+ {
+ status = kStatus_FLASH_EccError;
+ }
+ else if (registerValue & FLASH_INT_STATUS_OVL_MASK)
+ {
+ status = kStatus_FLASH_RegulationLoss;
+ }
+ else
+ {
+ status = kStatus_FLASH_Success;
+ }
+
+ return status;
+}
+
+/* Check if the Flash memory boundaries are not violated. */
+static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
+ uint32_t offset)
+{
+
+ uint32_t flash_limit = FLASH_TOTAL_SIZE - 1;
+
+ return (offset > flash_limit) ? (kStatus_Fail) : (kStatus_Success) ;
+}
+
+/* Check if the parameter is aligned to program_unit. */
+static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
+ uint32_t param)
+{
+ return ((param % flash_dev->data->program_unit) != 0) ? (kStatus_Fail) : (kStatus_Success);
+}