mcuboot/boot/cypress/cy_flash_pal/cy_smif_psoc6.c

144 lines
4.9 KiB
C

/***************************************************************************//**
* \file cy_smif_psoc6.c
* \version 1.0
*
* \brief
* This is the source file of external flash driver adoption layer between PSoC6
* and standard MCUBoot code.
*
********************************************************************************
* \copyright
*
* (c) 2020, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
* This software, including source code, documentation and related
* materials ("Software"), is owned by Cypress Semiconductor
* Corporation or one of its subsidiaries ("Cypress") and is protected by
* and subject to worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ("EULA").
*
* If no EULA applies, Cypress hereby grants you a personal, non-
* exclusive, non-transferable license to copy, modify, and compile the
* Software source code solely for use in connection with Cypress?s
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. Cypress reserves the right to make
* changes to the Software without notice. Cypress does not assume any
* liability arising out of the application or use of the Software or any
* product or circuit described in the Software. Cypress does not
* authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ("High Risk Product"). By
* including Cypress's product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
*
******************************************************************************/
#include "string.h"
#include "stdlib.h"
#include "stdbool.h"
#ifdef MCUBOOT_HAVE_ASSERT_H
#include "mcuboot_config/mcuboot_assert.h"
#else
#include <assert.h>
#endif
#include "flash_map_backend/flash_map_backend.h"
#include <sysflash/sysflash.h>
#include "cy_device_headers.h"
#include "cy_smif_psoc6.h"
#include "cy_flash.h"
#include "cy_syspm.h"
#include "flash_qspi.h"
#define PSOC6_WR_SUCCESS (0)
#define PSOC6_WR_ERROR_INVALID_PARAMETER (1)
#define PSOC6_WR_ERROR_FLASH_WRITE (2)
#define PSOC6_FLASH_ERASE_BLOCK_SIZE CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
int psoc6_smif_read(const struct flash_area *fap,
off_t addr,
void *data,
size_t len)
{
int rc = -1;
cy_stc_smif_mem_config_t *cfg;
cy_en_smif_status_t st;
uint32_t address;
cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
address = addr - CY_SMIF_BASE_MEM_OFFSET;
st = Cy_SMIF_MemRead(qspi_get_device(), cfg, address, data, len, qspi_get_context());
if (st == CY_SMIF_SUCCESS) {
rc = 0;
}
return rc;
}
int psoc6_smif_write(const struct flash_area *fap,
off_t addr,
const void *data,
size_t len)
{
int rc = -1;
cy_en_smif_status_t st;
cy_stc_smif_mem_config_t *cfg;
uint32_t address;
cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
address = addr - CY_SMIF_BASE_MEM_OFFSET;
st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, address, data, len, qspi_get_context());
if (st == CY_SMIF_SUCCESS) {
rc = 0;
}
return rc;
}
int psoc6_smif_erase(off_t addr, size_t size)
{
int rc = -1;
cy_en_smif_status_t st;
uint32_t address;
/* It is erase sector-only
*
* There is no power-safe way to erase flash partially
* this leads upgrade slots have to be at least
* eraseSectorSize far from each other;
*/
cy_stc_smif_mem_config_t *memCfg = qspi_get_memory_config(0);
address = (addr - CY_SMIF_BASE_MEM_OFFSET ) & ~((uint32_t)(memCfg->deviceCfg->eraseSize - 1u));
(void)size;
st = Cy_SMIF_MemEraseSector(qspi_get_device(),
memCfg,
address,
memCfg->deviceCfg->eraseSize,
qspi_get_context());
if (st == CY_SMIF_SUCCESS) {
rc = 0;
}
return rc;
}