mirror of https://github.com/ARMmbed/mbed-os.git
Refactor serial flash support
parent
70590006cb
commit
09182d1ed0
|
@ -1,11 +1,12 @@
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* \file cybsp_serial_flash_prog.c
|
* \file cy_serial_flash_prog.c
|
||||||
*
|
*
|
||||||
* \brief
|
* \brief
|
||||||
* Provides variables necessary to inform programming tools how to program the
|
* Provides variables necessary to inform programming tools how to program the
|
||||||
* attached serial flash memory. The variables used here must be placed at
|
* attached serial flash memory. The variables used here must be placed at
|
||||||
* specific locations in order to be detected and used by programming tools
|
* specific locations in order to be detected and used by programming tools
|
||||||
* to know that there is an attached memory and its characteristics.
|
* to know that there is an attached memory and its characteristics. Uses the
|
||||||
|
* configuration provided as part of BSP.
|
||||||
*
|
*
|
||||||
********************************************************************************
|
********************************************************************************
|
||||||
* \copyright
|
* \copyright
|
||||||
|
@ -26,22 +27,22 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup group_bsp_serial_flash Serial Flash
|
* \addtogroup group_serial_flash Serial Flash
|
||||||
* \{
|
* \{
|
||||||
* Variables for informing programming tools that there is an attached memory device and what
|
* 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.
|
* its characteristics are so it can be programmed just like the on-chip memory.
|
||||||
*
|
*
|
||||||
* \defgroup group_bsp_serial_flash_variables Variables
|
* \defgroup group_serial_flash_variables Variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "cybsp_types.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CYBSP_QSPI_SCK) && (DEVICE_QSPI)
|
#if defined(CY_ENABLE_XIP_PROGRAM)
|
||||||
|
|
||||||
#include "cycfg_qspi_memslot.h"
|
#include "cycfg_qspi_memslot.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -51,7 +52,7 @@ typedef struct
|
||||||
} stc_smif_ipblocks_arr_t;
|
} stc_smif_ipblocks_arr_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup group_bsp_serial_flash_variables
|
* \addtogroup group_serial_flash_variables
|
||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ typedef struct
|
||||||
* are multiple ways this can be accomplished including:
|
* are multiple ways this can be accomplished including:
|
||||||
* 1) Placing it in a dedicated memory block with a known address. (as done here)
|
* 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
|
* 2) Placing it at an absolute location via a the linker script
|
||||||
* 3) Using cymcuelftool to recompute the checksum and patch the elf file after linking
|
* 3) Using 'cymcuelftool -S' to recompute the checksum and patch the elf file after linking
|
||||||
*/
|
*/
|
||||||
CY_SECTION(".cy_sflash_user_data") __attribute__( (used) )
|
CY_SECTION(".cy_sflash_user_data") __attribute__( (used) )
|
||||||
const stc_smif_ipblocks_arr_t smifIpBlocksArr = {&smifBlockConfig, 0x00000000};
|
const stc_smif_ipblocks_arr_t smifIpBlocksArr = {&smifBlockConfig, 0x00000000};
|
||||||
|
@ -81,14 +82,21 @@ const uint32_t cyToc[128] =
|
||||||
0, /* Offset=0x0008: Key Storage Address */
|
0, /* Offset=0x0008: Key Storage Address */
|
||||||
(int)&smifIpBlocksArr, /* Offset=0x000C: This points to a null terminated array of SMIF structures. */
|
(int)&smifIpBlocksArr, /* Offset=0x000C: This points to a null terminated array of SMIF structures. */
|
||||||
0x10000000u, /* Offset=0x0010: App image start address */
|
0x10000000u, /* Offset=0x0010: App image start address */
|
||||||
[127] = 0x0B1F0000 /* Offset=0x01FC: CRC16-CCITT (the upper 2 bytes contain the CRC and the lower 2 bytes are 0) */
|
/* 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_bsp_serial_flash_variables */
|
/** \} group_serial_flash_variables */
|
||||||
#endif /* defined(CYBSP_QSPI_SCK) && (DEVICE_QSPI) */
|
|
||||||
|
#endif /* defined(CY_ENABLE_XIP_PROGRAM) */
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \} group_bsp_serial_flash */
|
/** \} group_serial_flash */
|
|
@ -0,0 +1,218 @@
|
||||||
|
/***************************************************************************//**
|
||||||
|
* \file cy_serial_flash_qspi.c
|
||||||
|
*
|
||||||
|
* \brief
|
||||||
|
* Provides APIs for interacting with an external flash connected to the SPI or
|
||||||
|
* QSPI interface, uses SFDP to auto-discover memory properties if SFDP is
|
||||||
|
* enabled in the configuration.
|
||||||
|
*
|
||||||
|
********************************************************************************
|
||||||
|
* \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 <stdbool.h>
|
||||||
|
#include "cy_serial_flash_qspi.h"
|
||||||
|
#include "cyhal_qspi.h"
|
||||||
|
#include "cy_utils.h"
|
||||||
|
|
||||||
|
#ifdef CY_IP_MXSMIF
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \cond internal */
|
||||||
|
|
||||||
|
/** Timeout to apply while polling the memory for its ready status after quad
|
||||||
|
* enable command has been sent out. Quad enable is a non-volatile write.
|
||||||
|
*/
|
||||||
|
#define CY_SERIAL_FLASH_QUAD_ENABLE_TIMEOUT_US (5000lu) /* in microseconds */
|
||||||
|
|
||||||
|
/* Number of memories supported by the driver */
|
||||||
|
#define SMIF_MEM_DEVICES (1u)
|
||||||
|
|
||||||
|
/* SMIF slot from which the memory configuration is picked up - fixed to 0 as the driver
|
||||||
|
* supports only one device */
|
||||||
|
#define MEM_SLOT (0u)
|
||||||
|
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
static cyhal_qspi_t qspi_obj;
|
||||||
|
|
||||||
|
static cy_stc_smif_mem_config_t * qspi_mem_config[SMIF_MEM_DEVICES];
|
||||||
|
|
||||||
|
static cy_stc_smif_block_config_t qspi_block_config =
|
||||||
|
{
|
||||||
|
/* The number of SMIF memories defined. */
|
||||||
|
.memCount = SMIF_MEM_DEVICES,
|
||||||
|
/* The pointer to the array of memory config structures of size memCount. */
|
||||||
|
.memConfig = (cy_stc_smif_mem_config_t**)qspi_mem_config,
|
||||||
|
/* The version of the SMIF driver. */
|
||||||
|
.majorVersion = CY_SMIF_DRV_VERSION_MAJOR,
|
||||||
|
/* The version of the SMIF driver. */
|
||||||
|
.minorVersion = CY_SMIF_DRV_VERSION_MINOR
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The driver supports only one memory. When multiple memory configurations
|
||||||
|
* are generated by the SMIF configurator tool, provide only the
|
||||||
|
* configuration for memory that need to be supported by the driver.
|
||||||
|
* Memory configuration can be changed by deinit followed by init with new
|
||||||
|
* configuration */
|
||||||
|
cy_rslt_t cy_serial_flash_qspi_init(
|
||||||
|
const cy_stc_smif_mem_config_t* mem_config,
|
||||||
|
cyhal_gpio_t io0,
|
||||||
|
cyhal_gpio_t io1,
|
||||||
|
cyhal_gpio_t io2,
|
||||||
|
cyhal_gpio_t io3,
|
||||||
|
cyhal_gpio_t io4,
|
||||||
|
cyhal_gpio_t io5,
|
||||||
|
cyhal_gpio_t io6,
|
||||||
|
cyhal_gpio_t io7,
|
||||||
|
cyhal_gpio_t sclk,
|
||||||
|
cyhal_gpio_t ssel,
|
||||||
|
uint32_t hz)
|
||||||
|
{
|
||||||
|
cy_en_smif_status_t smifStatus = CY_SMIF_SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
|
cy_rslt_t result = cyhal_qspi_init(&qspi_obj, io0, io1, io2, io3, io4, io5, io6, io7,
|
||||||
|
sclk, ssel, hz, 0);
|
||||||
|
|
||||||
|
qspi_mem_config[MEM_SLOT] = (cy_stc_smif_mem_config_t*) mem_config;
|
||||||
|
|
||||||
|
if(CY_RSLT_SUCCESS == result)
|
||||||
|
{
|
||||||
|
/* Perform SFDP detection and XIP register configuration depending on the
|
||||||
|
* memory configuration.
|
||||||
|
*/
|
||||||
|
smifStatus = Cy_SMIF_MemInit(qspi_obj.base, &qspi_block_config, &qspi_obj.context);
|
||||||
|
if(CY_SMIF_SUCCESS == smifStatus)
|
||||||
|
{
|
||||||
|
/* Enable Quad mode (1-1-4 or 1-4-4 modes) to use all the four I/Os during
|
||||||
|
* communication.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->readCmd->dataWidth == CY_SMIF_WIDTH_QUAD
|
||||||
|
|| qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->programCmd->dataWidth == CY_SMIF_WIDTH_QUAD)
|
||||||
|
{
|
||||||
|
bool isQuadEnabled = false;
|
||||||
|
smifStatus = Cy_SMIF_MemIsQuadEnabled(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], &isQuadEnabled, &qspi_obj.context);
|
||||||
|
if(CY_SMIF_SUCCESS == smifStatus)
|
||||||
|
{
|
||||||
|
if(!isQuadEnabled)
|
||||||
|
{
|
||||||
|
smifStatus = Cy_SMIF_MemEnableQuadMode(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], CY_SERIAL_FLASH_QUAD_ENABLE_TIMEOUT_US, &qspi_obj.context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((CY_RSLT_SUCCESS == result) && (CY_SMIF_SUCCESS == smifStatus))
|
||||||
|
{
|
||||||
|
return CY_RSLT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cy_SMIF_MemDeInit(qspi_obj.base);
|
||||||
|
cy_serial_flash_qspi_deinit();
|
||||||
|
return (cy_rslt_t)smifStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cy_serial_flash_qspi_deinit(void)
|
||||||
|
{
|
||||||
|
Cy_SMIF_MemDeInit(qspi_obj.base);
|
||||||
|
cyhal_qspi_free(&qspi_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cy_serial_flash_qspi_get_size(void)
|
||||||
|
{
|
||||||
|
return (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->memSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* address is ignored for the memory with uniform sector size. Currently,
|
||||||
|
* QSPI Configurator does not support memories with hybrid sectors.
|
||||||
|
*/
|
||||||
|
size_t cy_serial_flash_qspi_get_erase_size(uint32_t addr)
|
||||||
|
{
|
||||||
|
CY_UNUSED_PARAMETER(addr);
|
||||||
|
return (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->eraseSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
cy_rslt_t cy_serial_flash_qspi_read(uint32_t addr, size_t length, uint8_t *buf)
|
||||||
|
{
|
||||||
|
/* Cy_SMIF_MemRead() returns error if (addr + length) > total flash size. */
|
||||||
|
return (cy_rslt_t)Cy_SMIF_MemRead(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], addr, buf, length, &qspi_obj.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
cy_rslt_t cy_serial_flash_qspi_write(uint32_t addr, size_t length, const uint8_t *buf)
|
||||||
|
{
|
||||||
|
/* Cy_SMIF_MemWrite() returns error if (addr + length) > total flash size. */
|
||||||
|
return (cy_rslt_t)Cy_SMIF_MemWrite(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], addr, (uint8_t *)buf, length, &qspi_obj.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does not support hybrid sectors, sector size must be uniform on the entire
|
||||||
|
* chip. Use cy_serial_flash_qspi_get_erase_size(addr) to implement hybrid sector
|
||||||
|
* support when QSPI Configurator and PDL supports memories with hybrid sectors.
|
||||||
|
*/
|
||||||
|
cy_rslt_t cy_serial_flash_qspi_erase(uint32_t addr, size_t length)
|
||||||
|
{
|
||||||
|
cy_en_smif_status_t smifStatus;
|
||||||
|
|
||||||
|
/* If the erase is for the entire chip, use chip erase command */
|
||||||
|
if((addr == 0u) && (length == cy_serial_flash_qspi_get_size()))
|
||||||
|
{
|
||||||
|
smifStatus = Cy_SMIF_MemEraseChip(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], &qspi_obj.context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Cy_SMIF_MemEraseSector() returns error if (addr + length) > total flash size
|
||||||
|
* or if addr is not aligned to erase sector size or if (addr + length)
|
||||||
|
* is not aligned to erase sector size.
|
||||||
|
*/
|
||||||
|
smifStatus = Cy_SMIF_MemEraseSector(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT], addr, length, &qspi_obj.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cy_rslt_t)smifStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function enables or disables XIP on the MCU, does not send any command
|
||||||
|
// to the serial flash. XIP register configuration is already done as part of
|
||||||
|
// cy_serial_flash_qspi_init() if MMIO mode is enabled in the QSPI
|
||||||
|
// Configurator.
|
||||||
|
cy_rslt_t cy_serial_flash_qspi_enable_xip(bool enable)
|
||||||
|
{
|
||||||
|
if(enable)
|
||||||
|
{
|
||||||
|
Cy_SMIF_SetMode(qspi_obj.base, CY_SMIF_MEMORY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cy_SMIF_SetMode(qspi_obj.base, CY_SMIF_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CY_RSLT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CY_IP_MXSMIF */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* \file cybsp_serial_flash.h
|
* \file cy_serial_flash_qspi.h
|
||||||
*
|
*
|
||||||
* \brief
|
* \brief
|
||||||
* Provides APIs for interacting with an external flash connected to the SPI or
|
* Provides APIs for interacting with an external flash connected to the SPI or
|
||||||
|
@ -25,55 +25,83 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup group_bsp_serial_flash Serial Flash
|
* \addtogroup group_serial_flash Serial Flash
|
||||||
* \{
|
* \{
|
||||||
* Driver for interfacing with the serial flash (QSPI NOR flash) on Cypress boards.
|
* Driver for interfacing with the serial flash (QSPI NOR flash).
|
||||||
*
|
*
|
||||||
* \defgroup group_bsp_serial_flash_macros Macros
|
* \defgroup group_serial_flash_macros Macros
|
||||||
* \defgroup group_bsp_serial_flash_functions Functions
|
* \defgroup group_serial_flash_functions Functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "cy_result.h"
|
#include "cy_result.h"
|
||||||
|
#include "cy_pdl.h"
|
||||||
|
#include "cyhal.h"
|
||||||
|
|
||||||
|
#ifdef CY_IP_MXSMIF
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup group_bsp_serial_flash_macros
|
* \addtogroup group_serial_flash_macros
|
||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** The function or operation is not supported on the target or the memory */
|
/** The function or operation is not supported on the target or the memory */
|
||||||
#define CYBSP_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_BSP, 6))
|
#define CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 1))
|
||||||
|
|
||||||
/** \} group_bsp_serial_flash_macros */
|
/** \} group_serial_flash_macros */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup group_bsp_serial_flash_functions
|
* \addtogroup group_serial_flash_functions
|
||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initializes the serial flash on the board.
|
* \brief Initializes the serial flash memory.
|
||||||
|
* \param mem_config Memory configuration to be used for initializing
|
||||||
|
* \param io0 Data/IO pin 0 connected to the memory
|
||||||
|
* \param io1 Data/IO pin 1 connected to the memory
|
||||||
|
* \param io2 Data/IO pin 2 connected to the memory
|
||||||
|
* \param io3 Data/IO pin 3 connected to the memory
|
||||||
|
* \param io4 Data/IO pin 4 connected to the memory
|
||||||
|
* \param io5 Data/IO pin 5 connected to the memory
|
||||||
|
* \param io6 Data/IO pin 6 connected to the memory
|
||||||
|
* \param io7 Data/IO pin 7 connected to the memory
|
||||||
|
* \param sclk Clock pin connected to the memory
|
||||||
|
* \param ssel Slave select pin connected to the memory
|
||||||
|
* \param hz Clock frequency to be used with the memory
|
||||||
* \returns CY_RSLT_SUCCESS if the initialization was successful, an error code
|
* \returns CY_RSLT_SUCCESS if the initialization was successful, an error code
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cybsp_serial_flash_init(void);
|
cy_rslt_t cy_serial_flash_qspi_init(
|
||||||
|
const cy_stc_smif_mem_config_t* mem_config,
|
||||||
|
cyhal_gpio_t io0,
|
||||||
|
cyhal_gpio_t io1,
|
||||||
|
cyhal_gpio_t io2,
|
||||||
|
cyhal_gpio_t io3,
|
||||||
|
cyhal_gpio_t io4,
|
||||||
|
cyhal_gpio_t io5,
|
||||||
|
cyhal_gpio_t io6,
|
||||||
|
cyhal_gpio_t io7,
|
||||||
|
cyhal_gpio_t sclk,
|
||||||
|
cyhal_gpio_t ssel,
|
||||||
|
uint32_t hz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief De-initializes the serial flash on the board.
|
* \brief De-initializes the serial flash memory.
|
||||||
*/
|
*/
|
||||||
void cybsp_serial_flash_deinit(void);
|
void cy_serial_flash_qspi_deinit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Returns the size of the serial flash on the board in bytes.
|
* \brief Returns the size of the serial flash memory in bytes.
|
||||||
* \returns Memory size in bytes.
|
* \returns Memory size in bytes.
|
||||||
*/
|
*/
|
||||||
size_t cybsp_serial_flash_get_size(void);
|
size_t cy_serial_flash_qspi_get_size(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Returns the size of the erase sector to which the given address
|
* \brief Returns the size of the erase sector to which the given address
|
||||||
|
@ -81,38 +109,38 @@ size_t cybsp_serial_flash_get_size(void);
|
||||||
* \param addr Address that belongs to the sector for which size is returned.
|
* \param addr Address that belongs to the sector for which size is returned.
|
||||||
* \returns Erase sector size in bytes.
|
* \returns Erase sector size in bytes.
|
||||||
*/
|
*/
|
||||||
size_t cybsp_serial_flash_get_erase_size(uint32_t addr);
|
size_t cy_serial_flash_qspi_get_erase_size(uint32_t addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Reads data from the serial flash on the board. This is a blocking
|
* \brief Reads data from the serial flash memory. This is a blocking
|
||||||
* function. Returns error if (addr + length) exceeds the flash size.
|
* function. Returns error if (addr + length) exceeds the flash size.
|
||||||
* \param addr Starting address to read from
|
* \param addr Starting address to read from
|
||||||
* \param length Number of data bytes to read
|
* \param length Number of data bytes to read
|
||||||
* \param buf Pointer to the buffer to store the data read from the memory
|
* \param buf Pointer to the buffer to store the data read from the memory
|
||||||
* \returns CY_RSLT_SUCCESS if the read was successful, an error code otherwise.
|
* \returns CY_RSLT_SUCCESS if the read was successful, an error code otherwise.
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cybsp_serial_flash_read(uint32_t addr, size_t length, uint8_t *buf);
|
cy_rslt_t cy_serial_flash_qspi_read(uint32_t addr, size_t length, uint8_t *buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Writes the data to the serial flash on the board. The program area
|
* \brief Writes the data to the serial flash memory. The program area
|
||||||
* must have been erased prior to calling this API using
|
* must have been erased prior to calling this API using
|
||||||
* \ref cybsp_serial_flash_erase() This is a blocking function. Returns error if
|
* \ref cy_serial_flash_qspi_erase() This is a blocking function. Returns error if
|
||||||
* (addr + length) exceeds the flash size.
|
* (addr + length) exceeds the flash size.
|
||||||
* \param addr Starting address to write to
|
* \param addr Starting address to write to
|
||||||
* \param length Number of bytes to write
|
* \param length Number of bytes to write
|
||||||
* \param buf Pointer to the buffer storing the data to be written
|
* \param buf Pointer to the buffer storing the data to be written
|
||||||
* \returns CY_RSLT_SUCCESS if the write was successful, an error code
|
* \returns CY_RSLT_SUCCESS if the write was successful, an error code
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cybsp_serial_flash_write(uint32_t addr, size_t length, const uint8_t *buf);
|
cy_rslt_t cy_serial_flash_qspi_write(uint32_t addr, size_t length, const uint8_t *buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Erases the serial flash on the board, uses chip erase command when
|
* \brief Erases the serial flash memory, uses chip erase command when
|
||||||
* addr = 0 and length = flash_size otherwise uses sector erase command. This is
|
* addr = 0 and length = flash_size otherwise uses sector erase command. This is
|
||||||
* a blocking function. Returns error if addr or (addr + length) is not aligned
|
* a blocking function. Returns error if addr or (addr + length) is not aligned
|
||||||
* to the sector size or if (addr + length) exceeds the flash size.
|
* to the sector size or if (addr + length) exceeds the flash size.
|
||||||
* Call \ref cybsp_serial_flash_get_size() to get the flash size and
|
* Call \ref cy_serial_flash_qspi_get_size() to get the flash size and
|
||||||
* call \ref cybsp_serial_flash_get_erase_size() to get the size of an erase
|
* call \ref cy_serial_flash_qspi_get_erase_size() to get the size of an erase
|
||||||
* sector.
|
* sector.
|
||||||
*
|
*
|
||||||
* \param addr Starting address to begin erasing
|
* \param addr Starting address to begin erasing
|
||||||
|
@ -120,24 +148,26 @@ cy_rslt_t cybsp_serial_flash_write(uint32_t addr, size_t length, const uint8_t *
|
||||||
* \returns CY_RSLT_SUCCESS if the erase was successful, an error code
|
* \returns CY_RSLT_SUCCESS if the erase was successful, an error code
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cybsp_serial_flash_erase(uint32_t addr, size_t length);
|
cy_rslt_t cy_serial_flash_qspi_erase(uint32_t addr, size_t length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Enables Execute-in-Place (memory mapped) mode on the MCU. This
|
* \brief Enables Execute-in-Place (memory mapped) mode on the MCU. This
|
||||||
* function does not send any command to the serial flash. This may not be
|
* function does not send any command to the serial flash. This may not be
|
||||||
* supported on all the targets in which case
|
* supported on all the targets in which case
|
||||||
* CYBSP_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED is returned.
|
* CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED is returned.
|
||||||
* \param enable true: XIP mode is set, false: normal mode is set
|
* \param enable true: XIP mode is set, false: normal mode is set
|
||||||
* \returns CY_RSLT_SUCCESS if the operation was successful.
|
* \returns CY_RSLT_SUCCESS if the operation was successful.
|
||||||
* CYBSP_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED if the target does not
|
* CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED if the target does not
|
||||||
* support XIP.
|
* support XIP.
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cybsp_serial_flash_enable_xip(bool enable);
|
cy_rslt_t cy_serial_flash_qspi_enable_xip(bool enable);
|
||||||
|
|
||||||
/** \} group_bsp_serial_flash_functions */
|
/** \} group_serial_flash_functions */
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \} group_bsp_serial_flash */
|
#endif /* CY_IP_MXSMIF */
|
||||||
|
|
||||||
|
/** \} group_serial_flash */
|
|
@ -1,180 +0,0 @@
|
||||||
/***************************************************************************//**
|
|
||||||
* \file cybsp_serial_flash.c
|
|
||||||
*
|
|
||||||
* \brief
|
|
||||||
* Provides APIs for interacting with an external flash connected to the SPI or
|
|
||||||
* QSPI interface, uses the configuration generated by the QSPI configurator,
|
|
||||||
* uses SFDP to auto-discover memory properties if SFDP is enabled in the
|
|
||||||
* configuration.
|
|
||||||
*
|
|
||||||
********************************************************************************
|
|
||||||
* \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 <stdbool.h>
|
|
||||||
#include "cybsp_serial_flash.h"
|
|
||||||
#include "cy_pdl.h"
|
|
||||||
#include "cyhal_qspi.h"
|
|
||||||
#include "cy_utils.h"
|
|
||||||
#include "cybsp.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CYBSP_QSPI_SCK)
|
|
||||||
#include "cycfg_qspi_memslot.h"
|
|
||||||
|
|
||||||
/** \cond internal */
|
|
||||||
|
|
||||||
#define QSPI_BUS_FREQUENCY_HZ (50000000lu)
|
|
||||||
|
|
||||||
/** Timeout to apply while polling the memory for its ready status after quad
|
|
||||||
* enable command has been sent out. Quad enable is a non-volatile write.
|
|
||||||
*/
|
|
||||||
#define CYBSP_SERIAL_FLASH_QUAD_ENABLE_TIMEOUT_US (5000lu) /* in microseconds */
|
|
||||||
|
|
||||||
/* SMIF slot number to which the memory is connected */
|
|
||||||
#define MEM_SLOT (0u)
|
|
||||||
|
|
||||||
/** \endcond */
|
|
||||||
|
|
||||||
static cyhal_qspi_t qspi_obj;
|
|
||||||
|
|
||||||
cy_rslt_t cybsp_serial_flash_init(void)
|
|
||||||
{
|
|
||||||
cy_en_smif_status_t smifStatus = CY_SMIF_SUCCESS;
|
|
||||||
|
|
||||||
cy_rslt_t result = cyhal_qspi_init(&qspi_obj, CYBSP_QSPI_D0, CYBSP_QSPI_D1, CYBSP_QSPI_D2, CYBSP_QSPI_D3, NC, NC, NC, NC,
|
|
||||||
CYBSP_QSPI_SCK, CYBSP_QSPI_SS, QSPI_BUS_FREQUENCY_HZ, 0);
|
|
||||||
if(CY_RSLT_SUCCESS == result)
|
|
||||||
{
|
|
||||||
/* Perform SFDP detection and XIP register configuration depending on the
|
|
||||||
* memory configuration.
|
|
||||||
*/
|
|
||||||
smifStatus = Cy_SMIF_Memslot_Init(qspi_obj.base, (cy_stc_smif_block_config_t *) &smifBlockConfig, &qspi_obj.context);
|
|
||||||
if(CY_SMIF_SUCCESS == smifStatus)
|
|
||||||
{
|
|
||||||
/* Enable Quad mode (1-1-4 or 1-4-4 modes) to use all the four I/Os during
|
|
||||||
* communication.
|
|
||||||
*/
|
|
||||||
if(smifMemConfigs[MEM_SLOT]->deviceCfg->readCmd->dataWidth == CY_SMIF_WIDTH_QUAD
|
|
||||||
|| smifMemConfigs[MEM_SLOT]->deviceCfg->programCmd->dataWidth == CY_SMIF_WIDTH_QUAD)
|
|
||||||
{
|
|
||||||
bool isQuadEnabled = false;
|
|
||||||
smifStatus = Cy_SMIF_MemIsQuadEnabled(qspi_obj.base, smifMemConfigs[MEM_SLOT], &isQuadEnabled, &qspi_obj.context);
|
|
||||||
if(CY_SMIF_SUCCESS == smifStatus)
|
|
||||||
{
|
|
||||||
if(!isQuadEnabled)
|
|
||||||
{
|
|
||||||
smifStatus = Cy_SMIF_MemEnableQuadMode(qspi_obj.base, smifMemConfigs[MEM_SLOT], CYBSP_SERIAL_FLASH_QUAD_ENABLE_TIMEOUT_US, &qspi_obj.context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((CY_RSLT_SUCCESS == result) && (CY_SMIF_SUCCESS == smifStatus))
|
|
||||||
{
|
|
||||||
return CY_RSLT_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cybsp_serial_flash_deinit();
|
|
||||||
return (cy_rslt_t)smifStatus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cybsp_serial_flash_deinit(void)
|
|
||||||
{
|
|
||||||
cyhal_qspi_free(&qspi_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cybsp_serial_flash_get_size(void)
|
|
||||||
{
|
|
||||||
return (size_t)smifMemConfigs[MEM_SLOT]->deviceCfg->memSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* address is ignored for the memory with uniform sector size. Currently,
|
|
||||||
* QSPI Configurator does not support memories with hybrid sectors.
|
|
||||||
*/
|
|
||||||
size_t cybsp_serial_flash_get_erase_size(uint32_t addr)
|
|
||||||
{
|
|
||||||
CY_UNUSED_PARAMETER(addr);
|
|
||||||
return (size_t)smifMemConfigs[MEM_SLOT]->deviceCfg->eraseSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
cy_rslt_t cybsp_serial_flash_read(uint32_t addr, size_t length, uint8_t *buf)
|
|
||||||
{
|
|
||||||
/* Cy_SMIF_MemRead() returns error if (addr + length) > total flash size. */
|
|
||||||
return (cy_rslt_t)Cy_SMIF_MemRead(qspi_obj.base, smifMemConfigs[MEM_SLOT], addr, buf, length, &qspi_obj.context);
|
|
||||||
}
|
|
||||||
|
|
||||||
cy_rslt_t cybsp_serial_flash_write(uint32_t addr, size_t length, const uint8_t *buf)
|
|
||||||
{
|
|
||||||
/* Cy_SMIF_MemWrite() returns error if (addr + length) > total flash size. */
|
|
||||||
return (cy_rslt_t)Cy_SMIF_MemWrite(qspi_obj.base, smifMemConfigs[MEM_SLOT], addr, (uint8_t *)buf, length, &qspi_obj.context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does not support hybrid sectors, sector size must be uniform on the entire
|
|
||||||
* chip. Use cybsp_serial_flash_get_erase_size(addr) to implement hybrid sector
|
|
||||||
* support when QSPI Configurator and PDL supports memories with hybrid sectors.
|
|
||||||
*/
|
|
||||||
cy_rslt_t cybsp_serial_flash_erase(uint32_t addr, size_t length)
|
|
||||||
{
|
|
||||||
cy_en_smif_status_t smifStatus;
|
|
||||||
|
|
||||||
/* If the erase is for the entire chip, use chip erase command */
|
|
||||||
if((addr == 0u) && (length == cybsp_serial_flash_get_size()))
|
|
||||||
{
|
|
||||||
smifStatus = Cy_SMIF_MemEraseChip(qspi_obj.base, smifMemConfigs[MEM_SLOT], &qspi_obj.context);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Cy_SMIF_MemEraseSector() returns error if (addr + length) > total flash size
|
|
||||||
* or if addr is not aligned to erase sector size or if (addr + length)
|
|
||||||
* is not aligned to erase sector size.
|
|
||||||
*/
|
|
||||||
smifStatus = Cy_SMIF_MemEraseSector(qspi_obj.base, smifMemConfigs[MEM_SLOT], addr, length, &qspi_obj.context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (cy_rslt_t)smifStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function enables or disables XIP on the MCU, does not send any command
|
|
||||||
// to the serial flash. XIP register configuration is already done as part of
|
|
||||||
// cybsp_serial_flash_init() if MMIO mode is enabled in the QSPI
|
|
||||||
// Configurator.
|
|
||||||
cy_rslt_t cybsp_serial_flash_enable_xip(bool enable)
|
|
||||||
{
|
|
||||||
if(enable)
|
|
||||||
{
|
|
||||||
Cy_SMIF_SetMode(qspi_obj.base, CY_SMIF_MEMORY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cy_SMIF_SetMode(qspi_obj.base, CY_SMIF_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CY_RSLT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(CYBSP_QSPI_SCK) */
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -19,13 +19,13 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "cycfg.h"
|
#include "cycfg.h"
|
||||||
#include "cyhal_hwmgr.h"
|
#include "cyhal_hwmgr.h"
|
||||||
#include "cybsp_core.h"
|
#include "cybsp.h"
|
||||||
#include "mbed_power_mgmt.h"
|
#include "mbed_power_mgmt.h"
|
||||||
#include "rtos_idle.h"
|
#include "rtos_idle.h"
|
||||||
#include "us_ticker_api.h"
|
#include "us_ticker_api.h"
|
||||||
#if defined(CYBSP_ENABLE_FLASH_STORAGE)
|
#if defined(MBED_CONF_TARGET_XIP_ENABLE)
|
||||||
#include "cybsp_serial_flash.h"
|
#include "cy_serial_flash_qspi.h"
|
||||||
#endif /* defined(CYBSP_ENABLE_FLASH_STORAGE) */
|
#endif /* defined(MBED_CONF_TARGET_XIP_ENABLE) */
|
||||||
|
|
||||||
#if defined(COMPONENT_SPM_MAILBOX)
|
#if defined(COMPONENT_SPM_MAILBOX)
|
||||||
void mailbox_init(void);
|
void mailbox_init(void);
|
||||||
|
@ -93,8 +93,8 @@ void mbed_sdk_init(void)
|
||||||
|
|
||||||
#if MBED_CONF_TARGET_XIP_ENABLE
|
#if MBED_CONF_TARGET_XIP_ENABLE
|
||||||
/* The linker script allows storing data in external memory, if needed, enable access to that memory. */
|
/* The linker script allows storing data in external memory, if needed, enable access to that memory. */
|
||||||
cybsp_serial_flash_init();
|
cy_serial_flash_init();
|
||||||
cybsp_serial_flash_enable_xip(true);
|
cy_serial_flash_enable_xip(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enable global interrupts (disabled in CM4 startup assembly) */
|
/* Enable global interrupts (disabled in CM4 startup assembly) */
|
||||||
|
|
Loading…
Reference in New Issue