diff --git a/boot/cypress/BlinkyApp/BlinkyApp.mk b/boot/cypress/BlinkyApp/BlinkyApp.mk index 8c3dbfa7..a4ae9525 100644 --- a/boot/cypress/BlinkyApp/BlinkyApp.mk +++ b/boot/cypress/BlinkyApp/BlinkyApp.mk @@ -34,6 +34,10 @@ IMG_TYPE ?= BOOT # image type can be BOOT or UPGRADE IMG_TYPES = BOOT UPGRADE +# possible values are 0 and 0xff +# internal Flash by default +ERASED_VALUE ?= 0 + ifneq ($(COMPILER), GCC_ARM) $(error Only GCC ARM is supported at this moment) endif @@ -53,8 +57,8 @@ endif # Define start of application, RAM start and size, slot size ifeq ($(PLATFORM), PSOC_062_2M) - DEFINES_APP += -DRAM_START=0x08000000 - DEFINES_APP += -DRAM_SIZE=0x20000 + DEFINES_APP += -DRAM_START=0x08040000 + DEFINES_APP += -DRAM_SIZE=0x10000 DEFINES_APP += -DUSER_APP_START=0x10018000 SLOT_SIZE ?= 0x10000 endif @@ -80,7 +84,7 @@ ASM_FILES_APP := # We still need this for MCUBoot apps signing IMGTOOL_PATH ?= ../../scripts/imgtool.py -SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -v "2.0" -S $(SLOT_SIZE) -M 512 --overwrite-only -R 0 -k keys/$(SIGN_KEY_FILE).pem +SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -v "2.0" -S $(SLOT_SIZE) -M 512 --overwrite-only -R $(ERASED_VALUE) -k keys/$(SIGN_KEY_FILE).pem # Output folder OUT := $(APP_NAME)/out diff --git a/boot/cypress/BlinkyApp/toolchains.mk b/boot/cypress/BlinkyApp/toolchains.mk index 38684363..55c62d5c 100644 --- a/boot/cypress/BlinkyApp/toolchains.mk +++ b/boot/cypress/BlinkyApp/toolchains.mk @@ -48,7 +48,7 @@ endif # NOTE: Absolute pathes for now for the sake of development ifeq ($(HOST_OS), win) ifeq ($(COMPILER), GCC_ARM) - TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox_1.0/tools/gcc-7.2.1-1.0 + TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.1/gcc-7.2.1 MY_TOOLCHAIN_PATH:=$(subst \,/,$(TOOLCHAIN_PATH)) TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH) GCC_PATH := $(TOOLCHAIN_PATH) diff --git a/boot/cypress/MCUBootApp/ExternalMemory.md b/boot/cypress/MCUBootApp/ExternalMemory.md new file mode 100644 index 00000000..d2da5825 --- /dev/null +++ b/boot/cypress/MCUBootApp/ExternalMemory.md @@ -0,0 +1,78 @@ +### External Memory support for Secondary Slot + +**Description** + +Given document describes the use of external memory module as a secondary (upgrade) slot with Cypress' PSoC6 devices. + +The demonstration device is CY8CPROTO-062-4343W board which is PSoC6 device with 2M of Flash available. +The memory module present on board is S25FL512SAGMFI010 512-Mbit external Quad SPI NOR Flash. + +Using external memory for secondary slot allows to nearly double the size of Boot Image. + +**Operation Design and Flow** + +The design is based on using SFDP command's auto-discovery functionality of memory module IC and Cypress' SMIF PDL driver. + +It is assumed that user's design meets following: +* The memory-module used is SFDP-compliant; +* There only one module is being used for secondary slot; +* Only "OWERWRITE" bootloading scheme is used; +* The address for secondary slot should start from 0x18000000. +This corresponds to PSoC6's SMIF (Serial Memory InterFace) IP block mapping. +* The slot size for upgrade slot is even (or smaller) to erase size (0x40000) of given memory module. +This requirement is accepted for code simplicity. + +The default flash map implemented is the following: +* [0x10000000, 0x10018000] - MCUBootApp (bootloader) area; +* [0x10018000, 0x10028000] - primary slot for BlinkyApp; +* [0x18000000, 0x18010000] - secondary slot for BlinkyApp; +* [0x10038000, 0x10039000] - scratch area (not used); + +Size of slots `0x10000` - 64kB + +**Note 1**: make sure primary, secondary slot and bootloader app sizes are appropriate and correspond to flash area size defined in Applications' linker files. + +**Note 2**: make sure secondary slot start address is aligned (or smaller) to erase size (0x40000 - 256kB). + +MCUBootApp's `main.c` contains the call to Init-SFDP API which performs required GPIO configurations, SMIF IP block configurations, SFDP protocol read and memory-config structure initialization. + +After that MCUBootApp is ready to accept upgrade image from external memory module. + +Once valid upgrade image was accepted the image in external memory will be erased. + +**How to enable external memory support:** + +1. Seek for `CY_BOOT_USE_EXTERNAL_FLASH` in sources and define it in any: MCUBootApp.mk or any suitable header file. +2. Navigate to `cy_flash_map.c` and check if secondary slot start address and size meet the application's needs. +3. Define which slave select is used for external memory on a board by setting `smif_id` value in `main.c`. +4. Build MCUBootApp as described in `Readme.md`. + +**How to build upgrade image for external memory:** + + make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x7FE8000 ERASED_VALUE=0xff + +`HEADER_OFFSET` defines the offset from original boot image address. This one in line above suggests secondary slot will start from `0x18000000`. + +`ERASED_VALUE` defines the memory cell contents in erased state. It is `0x00` for PSoC6's internal Flash and `0xff` for S25FL512S. + +**Programming to external memory** + +The MCUBootApp programming can be done similarly to described in `Readme.md`: + + export OPENOCD=/Applications/ModusToolbox/tools_2.1/openocd + + ${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \ + -f ${OPENOCD}/scripts/interface/kitprog3.cfg \ + -f ${OPENOCD}/scripts/target/psoc6_2m.cfg \ + -c "init; psoc6 sflash_restrictions 1" \ + -c "init; reset init; program PATH_TO_APPLICATION.hex" \ + -c "resume; reset; exit" + +There is a NULL-pointer placed for SMIF configuration pointer in TOC2 (Table Of Contents, `cy_serial_flash_prog.c`). +This is done to force CY8PROTO-062-4343W DAP Link firmware to program external memory with hardcoded values. + +1. Press SW3 Mode button on a board to switch the board into DAP Link mode. +2. Once DAP Link removable disk appeared drop (copy) the upgrade image HEX file to it. +This will invoke firmware to program external memory. + +**Note 3:** the programming of external memory is limited to S25FL512S p/n only at this moment. diff --git a/boot/cypress/MCUBootApp/MCUBootApp.ld b/boot/cypress/MCUBootApp/MCUBootApp.ld index 832017bd..c6204799 100644 --- a/boot/cypress/MCUBootApp/MCUBootApp.ld +++ b/boot/cypress/MCUBootApp/MCUBootApp.ld @@ -63,7 +63,7 @@ MEMORY * Your changes must be aligned with the corresponding memory regions for the CM4 core in 'xx_cm4_dual.ld', * where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.ld'. */ - ram (rwx) : ORIGIN = 0x08000000, LENGTH = 0x20000 + ram (rwx) : ORIGIN = 0x08020000, LENGTH = 0x20000 flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x18000 /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. diff --git a/boot/cypress/MCUBootApp/MCUBootApp.mk b/boot/cypress/MCUBootApp/MCUBootApp.mk index 14cccf6a..d2a8ff81 100644 --- a/boot/cypress/MCUBootApp/MCUBootApp.mk +++ b/boot/cypress/MCUBootApp/MCUBootApp.mk @@ -45,6 +45,7 @@ DEFINES_APP := -DMBEDTLS_CONFIG_FILE="\"mcuboot_crypto_config.h\"" DEFINES_APP += -DECC256_KEY_FILE="\"keys/$(SIGN_KEY_FILE).pub\"" DEFINES_APP += -DCORE=$(CORE) DEFINES_APP += -DMCUBOOT_IMAGE_NUMBER=$(MCUBOOT_IMAGE_NUMBER) +DEFINES_APP += -DCY_BOOT_USE_EXTERNAL_FLASH ifeq ($(USE_CRYPTO_HW), 1) DEFINES_APP += -DMBEDTLS_USER_CONFIG_FILE="\"mcuboot_crypto_acc_config.h\"" @@ -53,8 +54,10 @@ endif SOURCES_MCUBOOT := $(wildcard $(CURDIR)/../bootutil/src/*.c) # Collect MCUBoot Application sources SOURCES_APP_SRC := $(wildcard $(CUR_APP_PATH)/*.c) + # Collect Flash Layer port sources SOURCES_FLASH_PORT := $(wildcard $(CURDIR)/cy_flash_pal/*.c) +SOURCES_FLASH_PORT += $(wildcard $(CURDIR)/cy_flash_pal/flash_qspi/*.c) # Collect all the sources SOURCES_APP := $(SOURCES_MCUBOOT) SOURCES_APP += $(SOURCES_APP_SRC) @@ -65,6 +68,7 @@ INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(CURDIR)/../bootutil/src) INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(CURDIR)/..) INCLUDE_DIRS_APP := $(addprefix -I, $(CURDIR)) +INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/flash_qspi) INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include) INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include/flash_map_backend) INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH)) diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h index 3a8eafea..0d6f7876 100644 --- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h +++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h @@ -94,4 +94,6 @@ int sim_log_enabled(int level); #define MCUBOOT_LOG_DBG(...) IGNORE(__VA_ARGS__) #endif +#define MCUBOOT_LOG_MODULE_DECLARE(...) + #endif /* MCUBOOT_LOGGING_H */ diff --git a/boot/cypress/MCUBootApp/cy_serial_flash_prog.c b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c new file mode 100644 index 00000000..512df93e --- /dev/null +++ b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c @@ -0,0 +1,100 @@ +/***************************************************************************//** +* \file cy_serial_flash_prog.c +* +* \brief +* Provides variables necessary to inform programming tools how to program the +* attached serial flash memory. The variables used here must be placed at +* specific locations in order to be detected and used by programming tools +* to know that there is an attached memory and its characteristics. Uses the +* configuration provided as part of BSP. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* 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 +* +* 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. +*******************************************************************************/ + +/** +* \addtogroup group_serial_flash Serial Flash +* \{ +* Variables for informing programming tools that there is an attached memory device and what +* its characteristics are so it can be programmed just like the on-chip memory. +* +* \defgroup group_serial_flash_variables Variables +*/ + +#include +#include "flash_qspi.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct +{ + const cy_stc_smif_block_config_t * smifCfg; /* Pointer to SMIF top-level configuration */ + const uint32_t null_t; /* NULL termination */ +} stc_smif_ipblocks_arr_t; + +/** +* \addtogroup group_serial_flash_variables +* \{ +*/ + +/** + * This data can be placed anywhere in the internal memory, but it must be at a location that + * can be determined and used for the calculation of the CRC16 checksum in the cyToc below. There + * are multiple ways this can be accomplished including: + * 1) Placing it in a dedicated memory block with a known address. (as done here) + * 2) Placing it at an absolute location via a the linker script + * 3) Using 'cymcuelftool -S' to recompute the checksum and patch the elf file after linking + */ +CY_SECTION(".cy_sflash_user_data") __attribute__( (used) ) +/* const stc_smif_ipblocks_arr_t smifIpBlocksArr = {&smifBlockConfig_sfdp, 0x00000000}; */ +/* if used zero-pointer to config, DAP link will use hardcoded config for CY8CPROTO-062-4343W */ +const stc_smif_ipblocks_arr_t smifIpBlocksArr = {0x00000000, 0x00000000}; + +/** + * This data is used to populate the table of contents part 2. When present, it is used by the boot + * process and programming tools to determine key characteristics about the memory usage including + * where the boot process should start the application from and what external memories are connected + * (if any). This must consume a full row of flash memory row. The last entry is a checksum of the + * other values in the ToC which must be updated if any other value changes. This can be done manually + * or by running 'cymcuelftool -S' to recompute the checksum. + */ +CY_SECTION(".cy_toc_part2") __attribute__( (used) ) +const uint32_t cyToc[128] = +{ + 0x200-4, /* Offset=0x0000: Object Size, bytes */ + 0x01211220, /* Offset=0x0004: Magic Number (TOC Part 2, ID) */ + 0, /* Offset=0x0008: Key Storage Address */ + (int)&smifIpBlocksArr, /* Offset=0x000C: This points to a null terminated array of SMIF structures. */ + 0x10000000u, /* Offset=0x0010: App image start address */ + /* Offset=0x0014-0x01F7: Reserved */ + [126] = 0x000002C2, /* Offset=0x01F8: Bits[ 1: 0] CLOCK_CONFIG (0=8MHz, 1=25MHz, 2=50MHz, 3=100MHz) + Bits[ 4: 2] LISTEN_WINDOW (0=20ms, 1=10ms, 2=1ms, 3=0ms, 4=100ms) + Bits[ 6: 5] SWJ_PINS_CTL (0/1/3=Disable SWJ, 2=Enable SWJ) + Bits[ 8: 7] APP_AUTHENTICATION (0/2/3=Enable, 1=Disable) + Bits[10: 9] FB_BOOTLOADER_CTL: UNUSED */ + [127] = 0x3BB30000 /* Offset=0x01FC: CRC16-CCITT (the upper 2 bytes contain the CRC and the lower 2 bytes are 0) */ +}; + +/** \} group_serial_flash_variables */ + +#if defined(__cplusplus) +} +#endif + +/** \} group_serial_flash */ diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c index e908d07c..968f0b6d 100644 --- a/boot/cypress/MCUBootApp/main.c +++ b/boot/cypress/MCUBootApp/main.c @@ -22,6 +22,11 @@ #include "cy_retarget_io_pdl.h" #include "cy_result.h" +#include "cycfg_clocks.h" +#include "cycfg_peripherals.h" +#include "cycfg_pins.h" + +#include "flash_qspi.h" #include "sysflash/sysflash.h" #include "flash_map_backend/flash_map_backend.h" @@ -56,6 +61,7 @@ static void do_boot(struct boot_rsp *rsp) int main(void) { struct boot_rsp rsp ; + cy_rslt_t rc = !CY_RSLT_SUCCESS; init_cycfg_clocks(); init_cycfg_peripherals(); @@ -68,11 +74,29 @@ int main(void) BOOT_LOG_INF("MCUBoot Bootloader Started"); - if (boot_go(&rsp) == 0) { - BOOT_LOG_INF("User Application validated successfully"); - do_boot(&rsp); - } else - BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images") ; - +#ifdef CY_BOOT_USE_EXTERNAL_FLASH + int smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */ + /* Acceptable values are: + * 0 - SMIF disabled (no external memory); + * 1, 2, 3 or 4 - slave select line memory module is connected to. + */ + rc = qspi_init_sfdp(smif_id); + if(rc == CY_SMIF_SUCCESS) + { + BOOT_LOG_INF("External Memory initialized w/ SFDP."); + } + else + { + BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%02x", (int)rc); + } + if(0 == rc) +#endif + { + if (boot_go(&rsp) == 0) { + BOOT_LOG_INF("User Application validated successfully"); + do_boot(&rsp); + } else + BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images") ; + } return 0; } diff --git a/boot/cypress/MCUBootApp/sysflash/sysflash.h b/boot/cypress/MCUBootApp/sysflash/sysflash.h index 2a905eec..f1fc8416 100644 --- a/boot/cypress/MCUBootApp/sysflash/sysflash.h +++ b/boot/cypress/MCUBootApp/sysflash/sysflash.h @@ -12,6 +12,12 @@ #define FLASH_AREA_IMAGE_2 5 #define FLASH_AREA_IMAGE_3 6 +/* Uncomment if external flash is being used */ +/* #define CY_BOOT_USE_EXTERNAL_FLASH */ + +/* use PDL-defined offset or one from SMFI config */ +#define CY_SMIF_BASE_MEM_OFFSET (0x18000000) + #define CY_FLASH_ALIGN (CY_FLASH_SIZEOF_ROW) #define CY_FLASH_DEVICE_BASE (CY_FLASH_BASE) diff --git a/boot/cypress/MCUBootApp/toolchains.mk b/boot/cypress/MCUBootApp/toolchains.mk index d250931f..562ce73e 100644 --- a/boot/cypress/MCUBootApp/toolchains.mk +++ b/boot/cypress/MCUBootApp/toolchains.mk @@ -48,7 +48,7 @@ endif # NOTE: Absolute pathes for now for the sake of development ifeq ($(HOST_OS), win) ifeq ($(COMPILER), GCC_ARM) - TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox_1.0/tools/gcc-7.2.1-1.0 + TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.1/gcc-7.2.1 MY_TOOLCHAIN_PATH:=$(subst \,/,$(TOOLCHAIN_PATH)) TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH) GCC_PATH := $(TOOLCHAIN_PATH) diff --git a/boot/cypress/Makefile b/boot/cypress/Makefile index b91f279d..3868c807 100644 --- a/boot/cypress/Makefile +++ b/boot/cypress/Makefile @@ -139,7 +139,7 @@ app: $(MAKE) post_build build: $(OUT_APP)/$(APP_NAME).hex - $(GCC_PATH)/bin/arm-none-eabi-objdump $(OUT_APP)/$(APP_NAME).hex -s > $(OUT_APP)/$(APP_NAME).lst + $(GCC_PATH)/bin/arm-none-eabi-objdump $(OUT_APP)/$(APP_NAME).elf -S --disassemble > $(OUT_APP)/$(APP_NAME).lst $(GCC_PATH)/bin/arm-none-eabi-objdump -h $(OUT_APP)/$(APP_NAME).elf $(GCC_PATH)/bin/arm-none-eabi-size --format=SysV $(OUT_APP)/$(APP_NAME).elf diff --git a/boot/cypress/cy_flash_pal/cy_flash_map.c b/boot/cypress/cy_flash_pal/cy_flash_map.c index 2b51795e..427c6c7a 100644 --- a/boot/cypress/cy_flash_pal/cy_flash_map.c +++ b/boot/cypress/cy_flash_pal/cy_flash_map.c @@ -36,12 +36,14 @@ #include "flash_map_backend/flash_map_backend.h" #include -#include "cy_flash_psoc6.h" #include "bootutil/bootutil_log.h" #include "cy_pdl.h" +#ifdef CY_BOOT_USE_EXTERNAL_FLASH +#include "cy_smif_psoc6.h" +#endif /* * For now, we only support one flash device. * @@ -86,6 +88,7 @@ static struct flash_area primary_1 = .fa_size = CY_BOOT_PRIMARY_1_SIZE }; +#ifndef CY_BOOT_USE_EXTERNAL_FLASH static struct flash_area secondary_1 = { .fa_id = FLASH_AREA_IMAGE_SECONDARY(0), @@ -95,7 +98,15 @@ static struct flash_area secondary_1 = CY_BOOT_PRIMARY_1_SIZE, .fa_size = CY_BOOT_SECONDARY_1_SIZE }; - +#else +static struct flash_area secondary_1 = +{ + .fa_id = FLASH_AREA_IMAGE_SECONDARY(0), + .fa_device_id = FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX), + .fa_off = CY_SMIF_BASE_MEM_OFFSET, + .fa_size = CY_BOOT_SECONDARY_1_SIZE +}; +#endif #if (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */ static struct flash_area primary_2 = { @@ -199,26 +210,30 @@ void flash_area_close(const struct flash_area *fa) (void)fa;/* Nothing to do there */ } -/* Reads `len` bytes of flash memory at `off` to the buffer at `dst` */ +/* +* Reads `len` bytes of flash memory at `off` to the buffer at `dst` +*/ int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst, uint32_t len) { int rc = 0; size_t addr; - if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) - { - assert(off < fa->fa_off); - assert(off + len < fa->fa_off); - + /* check if requested offset not less then flash area (fa) start */ + assert(off < fa->fa_off); + assert(off + len < fa->fa_off); + /* convert to absolute address inside a device*/ addr = fa->fa_off + off; - rc = psoc6_flash_read(addr, dst, len); + if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) + { + /* flash read by simple memory copying */ + memcpy((void *)dst, (const void*)addr, (size_t)len); } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement/split into psoc6_smif_read() + rc = psoc6_smif_read(fa, addr, dst, len); } #endif else @@ -230,29 +245,52 @@ int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst, if (rc != 0) { BOOT_LOG_ERR("Flash area read error, rc = %d", (int)rc); } - return rc; } -/* Writes `len` bytes of flash memory at `off` from the buffer at `src` */ +/* +* Writes `len` bytes of flash memory at `off` from the buffer at `src` + */ int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src, uint32_t len) { - int rc = 0; - size_t addr; + cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS; + size_t write_start_addr; + size_t write_end_addr; + const uint32_t * row_ptr = NULL; + + assert(off < fa->fa_off); + assert(off + len < fa->fa_off); + + /* convert to absolute address inside a device */ + write_start_addr = fa->fa_off + off; + write_end_addr = fa->fa_off + off + len; if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { - assert(off < fa->fa_off); - assert(off + len < fa->fa_off); + uint32_t row_number = 0; + uint32_t row_addr = 0; - addr = fa->fa_off + off; - rc = psoc6_flash_write(addr, src, len); + assert(!(len % CY_FLASH_SIZEOF_ROW)); + + row_number = (write_end_addr - write_start_addr) / CY_FLASH_SIZEOF_ROW; + row_addr = write_start_addr; + + row_ptr = (uint32_t *) src; + + for (uint32_t i = 1; i <= row_number + 1; i++){ + + rc = Cy_Flash_WriteRow(row_addr, row_ptr); + row_addr = write_start_addr + i * (uint32_t) CY_FLASH_SIZEOF_ROW; + + row_number--; + row_ptr = row_ptr + CY_FLASH_SIZEOF_ROW / 4; + } } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement/split into psoc6_smif_write() + rc = psoc6_smif_write(fa, write_start_addr, src, len); } #endif else @@ -261,27 +299,41 @@ int flash_area_write(const struct flash_area *fa, uint32_t off, rc = -1; } - return rc; + return (int) rc; } -/* Erases `len` bytes of flash memory at `off` */ +/*< Erases `len` bytes of flash memory at `off` */ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len) { - int rc = 0; - size_t addr; + cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS; + size_t erase_start_addr; + size_t erase_end_addr; + + assert(off < fa->fa_off); + assert(off + len < fa->fa_off); + assert(!(len % CY_FLASH_SIZEOF_ROW)); + + /* convert to absolute address inside a device*/ + erase_start_addr = fa->fa_off + off; + erase_end_addr = fa->fa_off + off + len; if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { - assert(off < fa->fa_off); - assert(off + len < fa->fa_off); + int row_number = 0; + uint32_t row_addr = 0; - addr = fa->fa_off + off; - rc = psoc6_flash_erase(addr, len); - } -#ifdef CY_USE_EXTERNAL_FLASH + row_number = (erase_end_addr - erase_start_addr) / CY_FLASH_SIZEOF_ROW; + + while (row_number != 0) + { + row_number--; + row_addr = erase_start_addr + row_number * (uint32_t) CY_FLASH_SIZEOF_ROW; + rc = Cy_Flash_EraseRow(row_addr); + } +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement/split into psoc6_smif_erase() + rc = psoc6_smif_erase(erase_start_addr, len); } #endif else @@ -289,21 +341,21 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len) /* incorrect/non-existing flash device id */ rc = -1; } - return rc; + return (int) rc; } -/* Returns this `flash_area`s alignment */ +/*< Returns this `flash_area`s alignment */ size_t flash_area_align(const struct flash_area *fa) { - uint8_t ret = -1; + int ret = -1; if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { ret = CY_FLASH_ALIGN; } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement for SMIF WR/ERASE size + return qspi_get_prog_size(); } #endif else @@ -315,22 +367,23 @@ size_t flash_area_align(const struct flash_area *fa) } #ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS -/* Initializes an array of flash_area elements for the slot's sectors */ +/*< Initializes an array of flash_area elements for the slot's sectors */ int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa) { int rc = 0; if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { - // TODO: (void)idx; (void)cnt; rc = 0; } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement/split into psoc6_smif_erase() + (void)idx; + (void)cnt; + rc = 0; } #endif else @@ -338,7 +391,6 @@ int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa) /* incorrect/non-existing flash device id */ rc = -1; } - return rc; } #endif @@ -387,12 +439,12 @@ uint8_t flash_area_erased_val(const struct flash_area *fap) if (fap->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { - ret = CY_BOOT_INTERNAL_FLASH_ERASE_VALUE ; + ret = CY_BOOT_INTERNAL_FLASH_ERASE_VALUE; } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if ((fap->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - ret = CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE ; + ret = CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE; } #endif else @@ -406,7 +458,6 @@ uint8_t flash_area_erased_val(const struct flash_area *fap) int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off, void *dst, uint32_t len) { - uint8_t i = 0; uint8_t *mem_dest; int rc; @@ -416,7 +467,7 @@ int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off, return -1; } - for (i = 0; i < len; i++) { + for (uint8_t i = 0; i < len; i++) { if (mem_dest[i] != flash_area_erased_val(fa)) { return 0; } @@ -424,14 +475,12 @@ int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off, return 1; } +#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret) { int rc = 0; uint32_t i = 0; - struct flash_area *fa; - size_t sector_size = 0; - size_t sectors_n = 0; - uint32_t addr = 0; + struct flash_area *fa = NULL; while(NULL != boot_area_descs[i]) { @@ -443,17 +492,20 @@ int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret) i++; } - if(NULL != boot_area_descs[i]) { + size_t sector_size = 0; + if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH) { sector_size = CY_FLASH_SIZEOF_ROW; } -#ifdef CY_USE_EXTERNAL_FLASH +#ifdef CY_BOOT_USE_EXTERNAL_FLASH else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG) { - // TODO: implement for SMIF + /* implement for SMIF */ + /* lets assume they are equal */ + sector_size = CY_FLASH_SIZEOF_ROW; } #endif else @@ -463,6 +515,9 @@ int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret) if(0 == rc) { + uint32_t addr = 0; + size_t sectors_n = 0; + sectors_n = (fa->fa_size + (sector_size - 1)) / sector_size; assert(sectors_n <= *cnt); @@ -484,3 +539,4 @@ int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret) return rc; } +#endif diff --git a/boot/cypress/cy_flash_pal/cy_flash_psoc6.c b/boot/cypress/cy_flash_pal/cy_flash_psoc6.c deleted file mode 100644 index 35dc30ff..00000000 --- a/boot/cypress/cy_flash_pal/cy_flash_psoc6.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2020 Cypress Semiconductors - * - * SPDX-License-Identifier: Apache-2.0 - */ - /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 "stdlib.h" -#include "stdbool.h" - -#ifdef MCUBOOT_HAVE_ASSERT_H -#include "mcuboot_config/mcuboot_assert.h" -#else -#include -#endif - -#include "cy_device_headers.h" -#include "cy_flash_psoc6.h" - -#include "cy_flash.h" -#include "cy_syspm.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_flash_read(off_t addr, void *data, size_t len) -{ - /* flash read by simple memory copying */ - memcpy((void *)data, (const void*)addr, (size_t)len); - - return 0; -} - -int psoc6_flash_write(off_t addr, - const void *data, size_t len) -{ - int rc; - - rc = psoc6_flash_write_hal((uint8_t *)data, addr, len); - - return rc; -} - -int psoc6_flash_erase(off_t addr, size_t size) -{ - int rc = 0; - - uint32_t addrStart, addrEnd, address; - uint32_t remStart, remEnd; - uint32_t rowIdxStart, rowIdxEnd, rowNum; - uint8_t buff[CY_FLASH_SIZEOF_ROW]; - - addrStart = addr; - addrEnd = addrStart + size; - - /* find if area bounds are aligned to rows */ - remStart = addrStart%CY_FLASH_SIZEOF_ROW; - remEnd = addrEnd%CY_FLASH_SIZEOF_ROW; - - /* find which row numbers are affected for full Erase */ - rowIdxStart = addrStart/CY_FLASH_SIZEOF_ROW; - rowIdxEnd = addrEnd/CY_FLASH_SIZEOF_ROW; - - if(remStart != 0) - {/* first row is fragmented, move to next */ - rowIdxStart++; - } - - /* total number of rows for full erase */ - rowNum = rowIdxEnd - rowIdxStart; - address = rowIdxStart*CY_FLASH_SIZEOF_ROW; - - while(rowNum>0) - { - rc = Cy_Flash_EraseRow(address); - assert(rc == 0); - address += CY_FLASH_SIZEOF_ROW; - rowNum--; - } - - /* if Start of erase area is unaligned */ - if(remStart != 0) - { - /* first row is fragmented, shift left by one*/ - rowIdxStart--; - - /* find start address of fragmented row */ - address = rowIdxStart*CY_FLASH_SIZEOF_ROW; - - /* store fragmented row contents first */ - memcpy((void *)buff, (const void*)address, remStart); - - /* erase fragmented row */ - rc = Cy_Flash_EraseRow(address); - assert(rc == 0); - - /* write stored back */ - rc = psoc6_flash_write_hal(buff, address, remStart); - assert(rc == 0); - } - /* if End of erase area is unaligned */ - if(remEnd != 0) - { - /* find start address of fragmented row */ - address = rowIdxEnd*CY_FLASH_SIZEOF_ROW; - - /* store fragmented row contents first */ - memcpy((void *)buff, (const void*)addrEnd, CY_FLASH_SIZEOF_ROW-remEnd); - - /* erase fragmented row */ - rc = Cy_Flash_EraseRow(address); - assert(rc == 0); - - /* write stored back */ - rc = psoc6_flash_write_hal(buff, addrEnd, CY_FLASH_SIZEOF_ROW-remEnd); - assert(rc == 0); - } - return rc; -} - -/******************************************************************************* -* Function Name: psoc6_flash_write_hal -****************************************************************************//** -* -* This function writes the data to the PSOC6's Flash. It will check the -* appropriate alignment of a start address and also perform an address range -* check based on the length before performing the write operation. -* This function performs memory compare and writes only row where there are new -* data to write. -* -* \param addr: Pointer to the buffer containing the data to be stored. -* \param data: Pointer to the array or variable in the flash. -* \param len: The length of the data in bytes. -* -* \return -* PSOC6_WR_SUCCESS A successful write -* PSOC6_WR_ERROR_INVALID_PARAMETER At least one of the input parameters is invalid -* PSOC6_WR__ERROR_FLASH_WRITE Error in flash Write -* -*******************************************************************************/ -int psoc6_flash_write_hal(uint8_t data[], - uint32_t address, - uint32_t len) -{ - int retCode; - cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS; - - uint32_t writeBuffer[CY_FLASH_SIZEOF_ROW / sizeof(uint32_t)]; - uint32_t rowId; - uint32_t dstIndex; - uint32_t srcIndex = 0u; - uint32_t eeOffset; - uint32_t byteOffset; - uint32_t rowsNotEqual; - uint8_t *writeBufferPointer; - - eeOffset = (uint32_t)address; - writeBufferPointer = (uint8_t*)writeBuffer; - - bool cond1; - - /* Make sure, that varFlash[] points to Flash */ - cond1 = ((eeOffset >= CY_FLASH_BASE) && - ((eeOffset + len) <= (CY_FLASH_BASE + CY_FLASH_SIZE))); - - if(cond1) - { - eeOffset -= CY_FLASH_BASE; - rowId = eeOffset / CY_FLASH_SIZEOF_ROW; - byteOffset = CY_FLASH_SIZEOF_ROW * rowId; - - while((srcIndex < len) && (rc == CY_FLASH_DRV_SUCCESS)) - { - rowsNotEqual = 0u; - /* Copy data to the write buffer either from the source buffer or from the flash */ - for(dstIndex = 0u; dstIndex < CY_FLASH_SIZEOF_ROW; dstIndex++) - { - if((byteOffset >= eeOffset) && (srcIndex < len)) - { - writeBufferPointer[dstIndex] = data[srcIndex]; - /* Detect that row programming is required */ - if((rowsNotEqual == 0u) && (CY_GET_REG8(CY_FLASH_BASE + byteOffset) != data[srcIndex])) - { - rowsNotEqual = 1u; - } - srcIndex++; - } - else - { - writeBufferPointer[dstIndex] = CY_GET_REG8(CY_FLASH_BASE + byteOffset); - } - byteOffset++; - } - - if(rowsNotEqual != 0u) - { - /* Write flash row */ - rc = Cy_Flash_WriteRow((rowId * CY_FLASH_SIZEOF_ROW) + CY_FLASH_BASE, writeBuffer); - } - - /* Go to the next row */ - rowId++; - } - } - else - { - rc = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS; - } - - /* Return error code */ - switch(rc) - { - case CY_FLASH_DRV_SUCCESS: - retCode = PSOC6_WR_SUCCESS; - break; - - case CY_FLASH_DRV_INVALID_INPUT_PARAMETERS: - case CY_FLASH_DRV_INVALID_FLASH_ADDR: - retCode = PSOC6_WR_ERROR_INVALID_PARAMETER; - break; - - default: - retCode = PSOC6_WR_ERROR_FLASH_WRITE; - break; - } - return(retCode); -} diff --git a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c b/boot/cypress/cy_flash_pal/cy_smif_psoc6.c new file mode 100644 index 00000000..62f71375 --- /dev/null +++ b/boot/cypress/cy_flash_pal/cy_smif_psoc6.c @@ -0,0 +1,143 @@ +/***************************************************************************//** +* \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 +#endif + +#include "flash_map_backend/flash_map_backend.h" +#include + +#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; +} diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c new file mode 100644 index 00000000..83e18555 --- /dev/null +++ b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c @@ -0,0 +1,475 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +/***************************************************************************//** +* \file flash_qspi.c +* \version 1.0 +* +* \brief +* This is the source file of external flash driver adaptation 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 "cy_pdl.h" +#include +#include "flash_qspi.h" + +#define CY_SMIF_SYSCLK_HFCLK_DIVIDER CY_SYSCLK_CLKHF_DIVIDE_BY_4 + +/* This is the board specific stuff that should align with your board. + * + * QSPI resources: + * + * SS0 - P11_2 + * SS1 - P11_1 + * SS2 - P11_0 + * SS3 - P12_4 + * + * D3 - P11_3 + * D2 - P11_4 + * D1 - P11_5 + * D0 - P11_6 + * + * SCK - P11_7 + * + * SMIF Block - SMIF0 + * + */ + +/* SMIF SlaveSelect Configurations */ +struct qspi_ss_config +{ + GPIO_PRT_Type* SS_Port; + int SS_Pin; + en_hsiom_sel_t SS_Mux; +}; + +#if (defined(PSOC_064_2M) || \ + defined(PSOC_064_1M) || \ + defined(PSOC_062_2M)) + #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 4 +#elif defined(PSOC_064_512K) + #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 3 +#else +#error "Platform device name is unsupported." +#endif +struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] = +{ + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 2, + .SS_Mux = P11_2_SMIF_SPI_SELECT0 + }, + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 1, + .SS_Mux = P11_1_SMIF_SPI_SELECT1 + }, + { + .SS_Port = GPIO_PRT11, + .SS_Pin = 0, + .SS_Mux = P11_0_SMIF_SPI_SELECT2 + }, +#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3) + { + .SS_Port = GPIO_PRT12, + .SS_Pin = 4, + .SS_Mux = P12_4_SMIF_SPI_SELECT3 + } +#endif +}; + +static GPIO_PRT_Type *D3Port = GPIO_PRT11; +static int D3Pin = 3; +static en_hsiom_sel_t D3MuxPort = P11_3_SMIF_SPI_DATA3; + +static GPIO_PRT_Type *D2Port = GPIO_PRT11; +static int D2Pin = 4; +static en_hsiom_sel_t D2MuxPort = P11_4_SMIF_SPI_DATA2; + +static GPIO_PRT_Type *D1Port = GPIO_PRT11; +static int D1Pin = 5; +static en_hsiom_sel_t D1MuxPort = P11_5_SMIF_SPI_DATA1; + +static GPIO_PRT_Type *D0Port = GPIO_PRT11; +static int D0Pin = 6; +static en_hsiom_sel_t D0MuxPort = P11_6_SMIF_SPI_DATA0; + +static GPIO_PRT_Type *SCKPort = GPIO_PRT11; +static int SCKPin = 7; +static en_hsiom_sel_t SCKMuxPort = P11_7_SMIF_SPI_CLK; + +static SMIF_Type *QSPIPort = SMIF0; + +cy_stc_smif_mem_cmd_t sfdpcmd = +{ + .command = 0x5A, + .cmdWidth = CY_SMIF_WIDTH_SINGLE, + .addrWidth = CY_SMIF_WIDTH_SINGLE, + .mode = 0xFFFFFFFFU, + .dummyCycles = 8, + .dataWidth = CY_SMIF_WIDTH_SINGLE, +}; + +static cy_stc_smif_mem_cmd_t rdcmd0; +static cy_stc_smif_mem_cmd_t wrencmd0; +static cy_stc_smif_mem_cmd_t wrdiscmd0; +static cy_stc_smif_mem_cmd_t erasecmd0; +static cy_stc_smif_mem_cmd_t chiperasecmd0; +static cy_stc_smif_mem_cmd_t pgmcmd0; +static cy_stc_smif_mem_cmd_t readsts0; +static cy_stc_smif_mem_cmd_t readstsqecmd0; +static cy_stc_smif_mem_cmd_t writestseqcmd0; + +static cy_stc_smif_mem_device_cfg_t dev_sfdp_0 = +{ + .numOfAddrBytes = 4, + .readSfdpCmd = &sfdpcmd, + .readCmd = &rdcmd0, + .writeEnCmd = &wrencmd0, + .writeDisCmd = &wrdiscmd0, + .programCmd = &pgmcmd0, + .eraseCmd = &erasecmd0, + .chipEraseCmd = &chiperasecmd0, + .readStsRegWipCmd = &readsts0, + .readStsRegQeCmd = &readstsqecmd0, + .writeStsRegQeCmd = &writestseqcmd0, +}; + +static cy_stc_smif_mem_config_t mem_sfdp_0 = +{ + /* The base address the memory slave is mapped to in the PSoC memory map. + Valid when the memory-mapped mode is enabled. */ + .baseAddress = 0x18000000U, + /* The size allocated in the PSoC memory map, for the memory slave device. + The size is allocated from the base address. Valid when the memory mapped mode is enabled. */ +/* .memMappedSize = 0x4000000U, */ + .flags = CY_SMIF_FLAG_DETECT_SFDP, + .slaveSelect = CY_SMIF_SLAVE_SELECT_0, + .dataSelect = CY_SMIF_DATA_SEL0, + .deviceCfg = &dev_sfdp_0 +}; + +cy_stc_smif_mem_config_t *mems_sfdp[1] = +{ + &mem_sfdp_0 +}; + +/* make it exported if used in TOC (cy_serial_flash_prog.c) */ +/* cy_stc_smif_block_config_t smifBlockConfig_sfdp = */ +static cy_stc_smif_block_config_t smifBlockConfig_sfdp = +{ + .memCount = 1, + .memConfig = mems_sfdp, +}; + +static cy_stc_smif_block_config_t *smif_blk_config; + +static cy_stc_smif_context_t QSPI_context; + +cy_stc_smif_config_t const QSPI_config = +{ + .mode = CY_SMIF_NORMAL, + .deselectDelay = 1, + .rxClockSel = CY_SMIF_SEL_INV_INTERNAL_CLK, + .blockEvent = CY_SMIF_BUS_ERROR +}; + +cy_stc_sysint_t smifIntConfig = +{/* ATTENTION: make sure proper Interrupts configured for CM0p or M4 cores */ + .intrSrc = NvicMux7_IRQn, + .cm0pSrc = smif_interrupt_IRQn, + .intrPriority = 1 +}; + +/* SMIF pinouts configurations */ +static cy_stc_gpio_pin_config_t QSPI_SS_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG_IN_OFF, + .hsiom = P11_2_SMIF_SPI_SELECT0, /* lets use SS0 by default */ + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +const cy_stc_gpio_pin_config_t QSPI_DATA3_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_3_SMIF_SPI_DATA3, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +const cy_stc_gpio_pin_config_t QSPI_DATA2_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_4_SMIF_SPI_DATA2, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +const cy_stc_gpio_pin_config_t QSPI_DATA1_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_5_SMIF_SPI_DATA1, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +const cy_stc_gpio_pin_config_t QSPI_DATA0_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG, + .hsiom = P11_6_SMIF_SPI_DATA0, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; +const cy_stc_gpio_pin_config_t QSPI_SCK_config = +{ + .outVal = 1, + .driveMode = CY_GPIO_DM_STRONG_IN_OFF, + .hsiom = P11_7_SMIF_SPI_CLK, + .intEdge = CY_GPIO_INTR_DISABLE, + .intMask = 0UL, + .vtrip = CY_GPIO_VTRIP_CMOS, + .slewRate = CY_GPIO_SLEW_FAST, + .driveSel = CY_GPIO_DRIVE_1_2, + .vregEn = 0UL, + .ibufMode = 0UL, + .vtripSel = 0UL, + .vrefSel = 0UL, + .vohSel = 0UL, +}; + +void Isr_SMIF(void) +{ + Cy_SMIF_Interrupt(QSPIPort, &QSPI_context); +} + +cy_en_smif_status_t qspi_init_hardware() +{ + cy_en_smif_status_t st; + + + Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config); + Cy_GPIO_SetHSIOM(D3Port, D3Pin, D3MuxPort); + + Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config); + Cy_GPIO_SetHSIOM(D2Port, D2Pin, D2MuxPort); + + Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config); + Cy_GPIO_SetHSIOM(D1Port, D1Pin, D1MuxPort); + + Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config); + Cy_GPIO_SetHSIOM(D0Port, D0Pin, D0MuxPort); + + Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config); + Cy_GPIO_SetHSIOM(SCKPort, SCKPin, SCKMuxPort); + + Cy_SysClk_ClkHfSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0); + Cy_SysClk_ClkHfSetDivider(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER); + Cy_SysClk_ClkHfEnable(CY_SYSCLK_CLKHF_IN_CLKPATH2); + + /* + * Setup the interrupt for the SMIF block. For the CM0 there + * is a two stage process to setup the interrupts. + */ + Cy_SysInt_Init(&smifIntConfig, Isr_SMIF); + + st = Cy_SMIF_Init(QSPIPort, &QSPI_config, 1000, &QSPI_context); + if (st != CY_SMIF_SUCCESS) + { + return st; + } + NVIC_EnableIRQ(smifIntConfig.intrSrc); /* Finally, Enable the SMIF interrupt */ + + Cy_SMIF_Enable(QSPIPort, &QSPI_context); + + return CY_SMIF_SUCCESS; +} + +cy_stc_smif_mem_config_t *qspi_get_memory_config(int index) +{ + return smif_blk_config->memConfig[index]; +} + +SMIF_Type *qspi_get_device() +{ + return QSPIPort; +} + +cy_stc_smif_context_t *qspi_get_context() +{ + return &QSPI_context; +} + +cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config) +{ + cy_en_smif_status_t st; + + st = qspi_init_hardware(); + if (st == CY_SMIF_SUCCESS) + { + smif_blk_config = blk_config; + st = Cy_SMIF_MemInit(QSPIPort, smif_blk_config, &QSPI_context); + } + return st; +} + +cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id) +{ + cy_en_smif_status_t stat = CY_SMIF_SUCCESS; + + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + + GPIO_PRT_Type *SS_Port; + int SS_Pin; + en_hsiom_sel_t SS_MuxPort; + + switch(smif_id) + { + case 1: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_0; + break; + case 2: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_1; + break; + case 3: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_2; + break; +#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3) + case 4: + (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_3; + break; +#endif + default: + stat = -1; + break; + } + + if(CY_SMIF_SUCCESS == stat) + { + SS_Port = qspi_SS_Configuration[smif_id-1].SS_Port; + SS_Pin = qspi_SS_Configuration[smif_id-1].SS_Pin; + SS_MuxPort = qspi_SS_Configuration[smif_id-1].SS_Mux; + + QSPI_SS_config.hsiom = SS_MuxPort; + + Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config); + Cy_GPIO_SetHSIOM(SS_Port, SS_Pin, SS_MuxPort); + + stat = qspi_init(&smifBlockConfig_sfdp); + } + return stat; +} + +uint32_t qspi_get_prog_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->programSize; +} + +uint32_t qspi_get_erase_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->eraseSize; +} + +uint32_t qspi_get_mem_size(void) +{ + cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig; + return (*memCfg)->deviceCfg->memSize; +} + diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h new file mode 100644 index 00000000..e7e213b5 --- /dev/null +++ b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h @@ -0,0 +1,68 @@ +/***************************************************************************//** +* \file flash_qspi.h +* \version 1.0 +* +* \brief +* This is the header file for PSoC6 external flash driver adoption layer. +* +******************************************************************************** +* \copyright +* +* © 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. +* +******************************************************************************/ +#ifndef __FLASH_QSPI_H__ +#define __FLASH_QSPI_H__ + +#include +#include "cy_pdl.h" + +/* make it exported if used in TOC (cy_serial_flash_prog.c) */ +/* cy_stc_smif_block_config_t smifBlockConfig_sfdp; */ + +cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id); +cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config); +cy_en_smif_status_t qspi_init_hardware(void); +uint32_t qspi_get_prog_size(void); +uint32_t qspi_get_erase_size(void); +uint32_t qspi_get_mem_size(void); + +SMIF_Type *qspi_get_device(void); +cy_stc_smif_context_t *qspi_get_context(void); +cy_stc_smif_mem_config_t *qspi_get_memory_config(int index); +void qspi_dump_device(cy_stc_smif_mem_device_cfg_t *dev); + +#endif /* __FLASH_QSPI_H__ */ diff --git a/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h b/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h deleted file mode 100644 index 09cea984..00000000 --- a/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018 Nordic Semiconductor ASA - * Copyright (c) 2015 Runtime Inc - * Copyright (c) 2020 Cypress Semiconductor Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - /*******************************************************************************/ - -#ifndef CY_FLASH_PSOC6_H_ -#define CY_FLASH_PSOC6_H_ - -#include "stddef.h" -#include "stdbool.h" - -#ifndef off_t -typedef long int off_t; -#endif - -int psoc6_flash_read(off_t addr, void *data, size_t len); -int psoc6_flash_write(off_t addr, const void *data, size_t len); -int psoc6_flash_erase(off_t addr, size_t size); - -int psoc6_flash_write_hal(uint8_t data[], - uint32_t address, - uint32_t len); -#endif /* CY_FLASH_PSOC6_H_ */ diff --git a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h b/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h new file mode 100644 index 00000000..fe1150d9 --- /dev/null +++ b/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h @@ -0,0 +1,64 @@ +/***************************************************************************//** +* \file cy_smif_psoc6.h +* \version 1.0 +* +* \brief +* This is the header file for PSoC6 SMIF driver adoption layer. +* +******************************************************************************** +* \copyright +* +* © 2019, 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. +* +******************************************************************************/ + +#ifndef CY_SMIF_PSOC6_H_ +#define CY_SMIF_PSOC6_H_ + +#include "stddef.h" +#include "stdbool.h" + +#include "flash_qspi.h" + +#ifndef off_t +typedef long int off_t; +#endif + +int psoc6_smif_read(const struct flash_area *fap, off_t addr, void *data, size_t len); +int psoc6_smif_write(const struct flash_area *fap, off_t addr, const void *data, size_t len); +int psoc6_smif_erase(off_t addr, size_t size); + +#endif /* CY_SMIF_PSOC6_H_ */ diff --git a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h b/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h index 53572322..da686181 100644 --- a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h +++ b/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h @@ -30,6 +30,16 @@ #include #include "cy_flash.h" +#define FLASH_DEVICE_INDEX_MASK (0x7F) +#define FLASH_DEVICE_GET_EXT_INDEX(n) ((n) & FLASH_DEVICE_INDEX_MASK) +#define FLASH_DEVICE_EXTERNAL_FLAG (0x80) +#define FLASH_DEVICE_INTERNAL_FLASH (0x7F) +#define FLASH_DEVICE_EXTERNAL_FLASH(index) (FLASH_DEVICE_EXTERNAL_FLAG | index) + +#ifndef CY_BOOT_EXTERNAL_DEVICE_INDEX +/* assume first(one) SMIF device is used */ +#define CY_BOOT_EXTERNAL_DEVICE_INDEX (0) +#endif /** * @@ -137,7 +147,9 @@ int flash_area_id_to_image_slot(int area_id); int flash_area_id_from_multi_image_slot(int image_index, int slot); int flash_area_id_to_multi_image_slot(int image_index, int area_id); - +#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS +int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret); +#endif /* * Returns the value expected to be read when accesing any erased * flash byte.