Cypress: fix flash_area_write, warnings, improve make, readme

Signed-off-by: Bohdan Kovalchuk <bohd@cypress.com>
diff --git a/boot/cypress/MCUBootApp/ExternalMemory.md b/boot/cypress/MCUBootApp/ExternalMemory.md
index d2da582..8cd7367 100644
--- a/boot/cypress/MCUBootApp/ExternalMemory.md
+++ b/boot/cypress/MCUBootApp/ExternalMemory.md
@@ -23,10 +23,30 @@
 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);
+
+Single-image mode.
+
+`[0x10000000, 0x10018000]` - MCUBootApp (bootloader) area;
+
+`[0x10018000, 0x10028000]` - primary slot for BlinkyApp;
+
+`[0x18000000, 0x18010000]` - secondary slot for BlinkyApp;
+
+`[0x10038000, 0x10039000]` - scratch area (not used);
+
+Multi(dual)-image mode.
+
+`[0x10000000, 0x10018000]` - MCUBootApp (bootloader) area;
+
+`[0x10018000, 0x10028000]` - primary1 slot for BlinkyApp;
+
+`[0x18000000, 0x18010000]` - secondary1 slot for BlinkyApp;
+
+`[0x10038000, 0x10048000]` - primary2 slot for user app ;
+
+`[0x18040000, 0x18050000]` - secondary2 slot for user app;
+
+`[0x10058000, 0x10059000]` - scratch area (not used);
 
 Size of slots `0x10000` - 64kB
 
@@ -47,6 +67,8 @@
 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`.
 
+**Note 3**: External memory code is developed basing on PDL and can be run on CM0p core only. It may require modifications if used on CM4.
+
 **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
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.mk b/boot/cypress/MCUBootApp/MCUBootApp.mk
index 7cd9450..a760848 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.mk
+++ b/boot/cypress/MCUBootApp/MCUBootApp.mk
@@ -41,6 +41,9 @@
 include $(CUR_APP_PATH)/libs.mk
 include $(CUR_APP_PATH)/toolchains.mk
 
+# default slot size is 0x10000, 512bytes per row/sector, so 128 sectors
+MAX_IMG_SECTORS ?= 128
+
 # Application-specific DEFINES
 DEFINES_APP := -DMBEDTLS_CONFIG_FILE="\"mcuboot_crypto_config.h\""
 DEFINES_APP += -DECC256_KEY_FILE="\"keys/$(SIGN_KEY_FILE).pub\""
@@ -49,6 +52,7 @@
 ifeq ($(USE_EXTERNAL_FLASH), 1)
 DEFINES_APP += -DCY_BOOT_USE_EXTERNAL_FLASH
 endif
+DEFINES_APP += -DMCUBOOT_MAX_IMG_SECTORS=$(MAX_IMG_SECTORS)
 
 ifeq ($(USE_CRYPTO_HW), 1)
 DEFINES_APP += -DMBEDTLS_USER_CONFIG_FILE="\"mcuboot_crypto_acc_config.h\""
diff --git a/boot/cypress/MCUBootApp/README.md b/boot/cypress/MCUBootApp/README.md
index 9db4b4b..2da2d7c 100644
--- a/boot/cypress/MCUBootApp/README.md
+++ b/boot/cypress/MCUBootApp/README.md
@@ -9,19 +9,26 @@
 * BlinkyApp - simple PSoC6 blinking LED application which is a target of BOOT/UPGRADE;
 
 The demonstration device is CY8CPROTO-062-4343W board which is PSoC6 device with 2M of Flash available.
-
 The default flash map implemented is the following:
 
-* [0x10000000, 0x10018000] - MCUBootApp (bootloader) area;
-* [0x10018000, 0x10028000] - primary slot for BlinkyApp;
-* [0x10028000, 0x10038000] - secondary slot for BlinkyApp;
-* [0x10038000, 0x10039000] - scratch area;
+Single-image mode.
+
+`[0x10000000, 0x10018000]` - MCUBootApp (bootloader) area;
+
+`[0x10018000, 0x10028000]` - primary slot for BlinkyApp;
+
+`[0x10028000, 0x10038000]` - secondary slot for BlinkyApp;
+
+`[0x10038000, 0x10039000]` - scratch area (not used);
 
 Size of slots `0x10000` - 64kb
 
+MCUBootApp checks image integrity with SHA256, image authenticity with EC256 digital signature verification and uses completely SW implementation of cryptographic functions based on mbedTLS Library.
+
 **Important**: make sure primary, secondary slot and bootloader app sizes are appropriate and correspond to flash area size defined in Applications' linker files.
 
-MCUBootApp checks image integrity with SHA256, image authenticity with EC256 digital signature verification and uses completely SW implementation of cryptographic functions based on mbedTLS Library.
+**Important**: make sure RAM areas of CM0p-based MCUBootApp bootloader and CM4-based BlinkyApp do not overlap.
+Memory (stack) corruption of CM0p application can cause failure if SystemCall-served operations invoked from CM4.
 
 **Hardware cryptography acceleration:**
 
@@ -72,7 +79,7 @@
 
 Multi-image operation considers upgrading and verification of more then one image on the device.
 
-To enable multi-image operation define `MCUBOOT_IMAGE_NUMBER` in `MCUBootApp/mcuboot_config.h` file should be set to 2 (only dual-image is supported at the moment). This could also be done on build time by passing `MCUBOOT_IMAGE_NUMBER=2` as parameter to `make`.
+To enable multi-image operation define `MCUBOOT_IMAGE_NUMBER` in `MCUBootApp/config/mcuboot_config.h` file should be set to 2 (only dual-image is supported at the moment). This could also be done on build time by passing `MCUBOOT_IMAGE_NUMBER=2` as parameter to `make`.
 
 Default value of `MCUBOOT_IMAGE_NUMBER` is 1, which corresponds to single image configuratios.
 
@@ -98,10 +105,13 @@
 
 `0x10048000 - 0x10058000` - Secondary_2 (UPGRADE) slot of Bootloader
 
-`0x10058000 - 0x10058100` - Scratch of Bootloader
+`0x10058000 - 0x10059000` - Scratch of Bootloader
 
 Size of slots `0x10000` - 64kb
 
+__Note:__ It is also possible to place secondary (upgrade) slots in external memory module so resulting image size can be doubled.
+For more details about External Memory usage, please refer to separate guiding document `ExternalMemory.md`.
+
 **Downloading Solution's Assets**
 
 There is a set assets required:
diff --git a/boot/cypress/MCUBootApp/cy_retarget_io_pdl.c b/boot/cypress/MCUBootApp/cy_retarget_io_pdl.c
deleted file mode 100644
index 2561ee5..0000000
--- a/boot/cypress/MCUBootApp/cy_retarget_io_pdl.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/***************************************************************************//**
-* \file cy_retarget_io.c
-*
-* \brief
-* Provides APIs for retargeting stdio to UART hardware contained on the Cypress
-* kits.
-*
-********************************************************************************
-* \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.
-*******************************************************************************/
-
-#include "cy_retarget_io_pdl.h"
-
-#include "cycfg_peripherals.h"
-
-#include "cy_sysint.h"
-#include "cy_scb_uart.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* Tracks the previous character sent to output stream */
-#ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-static char cy_retarget_io_stdout_prev_char = 0;
-#endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-
-cy_stc_scb_uart_context_t CYBSP_UART_context;
-
-static uint8_t cy_retarget_io_getchar(void);
-static void cy_retarget_io_putchar(char c);
-
-#if defined(__ARMCC_VERSION) /* ARM-MDK */
-    /***************************************************************************
-    * Function Name: fputc
-    ***************************************************************************/
-    __attribute__((weak)) int fputc(int ch, FILE *f)
-    {
-        (void)f;
-    #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-        if ((char)ch == '\n' && cy_retarget_io_stdout_prev_char != '\r')
-        {
-            cy_retarget_io_putchar('\r');
-        }
-
-        cy_retarget_io_stdout_prev_char = (char)ch;
-    #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-        cy_retarget_io_putchar(ch);
-        return (ch);
-    }
-#elif defined (__ICCARM__) /* IAR */
-    #include <yfuns.h>
-
-    /***************************************************************************
-    * Function Name: __write
-    ***************************************************************************/
-    __weak size_t __write(int handle, const unsigned char * buffer, size_t size)
-    {
-        size_t nChars = 0;
-        /* This template only writes to "standard out", for all other file
-        * handles it returns failure. */
-        if (handle != _LLIO_STDOUT)
-        {
-            return (_LLIO_ERROR);
-        }
-        if (buffer != NULL)
-        {
-            for (/* Empty */; nChars < size; ++nChars)
-            {
-            #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-                if (*buffer == '\n' && cy_retarget_io_stdout_prev_char != '\r')
-                {
-                    cy_retarget_io_putchar('\r');
-                }
-
-                cy_retarget_io_stdout_prev_char = *buffer;
-            #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-                cy_retarget_io_putchar(*buffer);
-                ++buffer;
-            }
-        }
-        return (nChars);
-    }
-#else /* (__GNUC__)  GCC */
-    /* Add an explicit reference to the floating point printf library to allow
-    the usage of floating point conversion specifier. */
-    __asm (".global _printf_float");
-    /***************************************************************************
-    * Function Name: _write
-    ***************************************************************************/
-    __attribute__((weak)) int _write (int fd, const char *ptr, int len)
-    {
-        int nChars = 0;
-        (void)fd;
-        if (ptr != NULL)
-        {
-            for (/* Empty */; nChars < len; ++nChars)
-            {
-            #ifdef CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-                if (*ptr == '\n' && cy_retarget_io_stdout_prev_char != '\r')
-                {
-                    cy_retarget_io_putchar('\r');
-                }
-
-                cy_retarget_io_stdout_prev_char = *ptr;
-            #endif /* CY_RETARGET_IO_CONVERT_LF_TO_CRLF */
-                cy_retarget_io_putchar((uint32_t)*ptr);
-                ++ptr;
-            }
-        }
-        return (nChars);
-    }
-#endif
-
-
-#if defined(__ARMCC_VERSION) /* ARM-MDK */
-    /***************************************************************************
-    * Function Name: fgetc
-    ***************************************************************************/
-    __attribute__((weak)) int fgetc(FILE *f)
-    {
-        (void)f;
-        return (cy_retarget_io_getchar());
-    }
-#elif defined (__ICCARM__) /* IAR */
-    __weak size_t __read(int handle, unsigned char * buffer, size_t size)
-    {
-        /* This template only reads from "standard in", for all other file
-        handles it returns failure. */
-        if ((handle != _LLIO_STDIN) || (buffer == NULL))
-        {
-            return (_LLIO_ERROR);
-        }
-        else
-        {
-            *buffer = cy_retarget_io_getchar();
-            return (1);
-        }
-    }
-#else /* (__GNUC__)  GCC */
-    /* Add an explicit reference to the floating point scanf library to allow
-    the usage of floating point conversion specifier. */
-    __asm (".global _scanf_float");
-    __attribute__((weak)) int _read (int fd, char *ptr, int len)
-    {
-        int nChars = 0;
-        (void)fd;
-        if (ptr != NULL)
-        {
-            for(/* Empty */;nChars < len;++ptr)
-            {
-                *ptr = (char)cy_retarget_io_getchar();
-                ++nChars;
-                if((*ptr == '\n') || (*ptr == '\r'))
-                {
-                    break;
-                }
-            }
-        }
-        return (nChars);
-    }
-#endif
-
-static uint8_t cy_retarget_io_getchar(void)
-{
-    uint32_t read_value = Cy_SCB_UART_Get(CYBSP_UART_HW);
-    while (read_value == CY_SCB_UART_RX_NO_DATA)
-    {
-        read_value = Cy_SCB_UART_Get(CYBSP_UART_HW);
-    }
-
-    return (uint8_t)read_value;
-}
-
-static void cy_retarget_io_putchar(char c)
-{
-    uint32_t count = 0;
-    while (count == 0)
-    {
-        count = Cy_SCB_UART_Put(CYBSP_UART_HW, c);
-    }
-}
-
-static cy_rslt_t cy_retarget_io_pdl_setbaud(CySCB_Type *base, uint32_t baudrate)
-{
-    cy_rslt_t status;
-
-    uint8_t oversample_value = 8u;
-    uint8_t frac_bits = 0u;
-    uint32_t divider;
-
-    Cy_SCB_UART_Disable(base, NULL);
-
-    Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_16_BIT, 0);
-
-    divider = ((Cy_SysClk_ClkPeriGetFrequency() * (1 << frac_bits)) + ((baudrate * oversample_value) / 2)) / (baudrate * oversample_value) - 1;
-
-    status = (cy_rslt_t) Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_16_BIT, 0u, divider);
-
-    Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_16_BIT, 0u);
-
-    Cy_SCB_UART_Enable(base);
-
-    return status;
-}
-
-cy_rslt_t cy_retarget_io_pdl_init(uint32_t baudrate)
-{
-    cy_rslt_t result;
-
-    /* Configure and enable UART */
-    (void)Cy_SCB_UART_Init(CYBSP_UART_HW, &CYBSP_UART_config, &CYBSP_UART_context);
-
-    cy_retarget_io_pdl_setbaud(CYBSP_UART_HW, baudrate);
-
-    Cy_SCB_UART_Enable(CYBSP_UART_HW);
-
-    result = CY_RSLT_SUCCESS;
-
-    return result;
-}
-
-void cy_retarget_io_pdl_deinit()
-{
-    Cy_SCB_UART_DeInit(CYBSP_UART_HW);
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/boot/cypress/MCUBootApp/cy_retarget_io_pdl.h b/boot/cypress/MCUBootApp/cy_retarget_io_pdl.h
deleted file mode 100644
index a12da22..0000000
--- a/boot/cypress/MCUBootApp/cy_retarget_io_pdl.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************//**
-* \file cy_retarget_io.h
-*
-* \brief
-* Provides APIs for transmitting messages to or from the board via standard
-* printf/scanf functions. Messages are transmitted over a UART connection which
-* is generally connected to a host machine. Transmission is done at 115200 baud
-* using the tx and rx pins provided by the user of this library. The UART
-* instance is made available via cy_retarget_io_uart_obj in case any changes
-* to the default configuration are desired.
-* NOTE: If the application is built using newlib-nano, by default, floating
-* point format strings (%f) are not supported. To enable this support you must
-* add '-u _printf_float' to the linker command line.
-*
-********************************************************************************
-* \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.
-*******************************************************************************/
-
-#pragma once
-
-#include <stdio.h>
-#include "cy_result.h"
-#include "cy_pdl.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/** UART baud rate */
-#define CY_RETARGET_IO_BAUDRATE             (115200)
-
-/** Defining this macro enables conversion of line feed (LF) into carriage
- * return followed by line feed (CR & LF) on the output direction (STDOUT). You
- * can define this macro through the DEFINES variable in the application
- * Makefile.
- */
-#define CY_RETARGET_IO_CONVERT_LF_TO_CRLF
-
-cy_rslt_t cy_retarget_io_pdl_init(uint32_t baudrate);
-
-void cy_retarget_io_pdl_deinit(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c
index 968f0b6..8976d31 100644
--- a/boot/cypress/MCUBootApp/main.c
+++ b/boot/cypress/MCUBootApp/main.c
@@ -48,6 +48,7 @@
     app_addr = (rsp->br_image_off + rsp->br_hdr->ih_hdr_size);
 
     BOOT_LOG_INF("Starting User Application on CM4 (wait)...");
+    BOOT_LOG_INF("Start Address: 0x%08x", app_addr);
     Cy_SysLib_Delay(100);
 
     Cy_SysEnableCM4(app_addr);
@@ -60,8 +61,7 @@
 
 int main(void)
 {
-    struct boot_rsp rsp ;
-    cy_rslt_t rc = !CY_RSLT_SUCCESS;
+    struct boot_rsp rsp;
 
     init_cycfg_clocks();
     init_cycfg_peripherals();
@@ -75,6 +75,13 @@
     BOOT_LOG_INF("MCUBoot Bootloader Started");
 
 #ifdef CY_BOOT_USE_EXTERNAL_FLASH
+    cy_rslt_t rc = !CY_RSLT_SUCCESS;
+
+    #undef MCUBOOT_MAX_IMG_SECTORS
+    /* redefine number of sectors as there 2MB will be
+     * available on PSoC062-2M in case of external
+     * memory usage */
+    #define MCUBOOT_MAX_IMG_SECTORS 4096
     int smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */
     /* Acceptable values are:
     * 0 - SMIF disabled (no external memory);
diff --git a/boot/cypress/MCUBootApp/platforms.mk b/boot/cypress/MCUBootApp/platforms.mk
index d4a70c5..d454a90 100644
--- a/boot/cypress/MCUBootApp/platforms.mk
+++ b/boot/cypress/MCUBootApp/platforms.mk
@@ -48,9 +48,11 @@
 # Collect C source files for PLATFORM
 SOURCES_PLATFORM += $(wildcard $(PLATFORM_PATH)/*.c)
 SOURCES_PLATFORM := $(filter-out %/system_psoc6_cm4.c, $(SOURCES_PLATFORM))
+SOURCES_PLATFORM += $(wildcard $(PLATFORM_PATH)/retarget_io_pdl/*.c)
 
 # Collect dirrectories containing headers for PLATFORM
 INCLUDE_DIRS_PLATFORM := $(PLATFORM_PATH)
+INCLUDE_DIRS_PLATFORM += $(PLATFORM_PATH)/retarget_io_pdl
 # Collect Assembler files for PLATFORM
 # Include _01_, _02_ or _03_ PLATFORM_SUFFIX depending on device family.
 STARTUP_FILE := $(PLATFORM_PATH)/$(PLATFORM)/$(CORE)/$(COMPILER)/startup_psoc6_$(PLATFORM_SUFFIX)_cm0plus