mirror of https://github.com/ARMmbed/mbed-os.git
Update serial-flash to 1.1.0.20805
parent
f489d579b0
commit
623e799d63
|
@ -1,98 +0,0 @@
|
|||
/***************************************************************************//**
|
||||
* \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-2020 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_board_libs
|
||||
* \{
|
||||
* In addition to the APIs for reading and writting to memory at runtime, this library also
|
||||
* provides support for informing programming tools about the external memory so it can be
|
||||
* be written at the same time as internal flash. This support can be enabled by defining
|
||||
* CY_ENABLE_XIP_PROGRAM while building the application. With this define in place, code
|
||||
* will be generated in the .cy_sflash_user_data & .cy_toc_part2 sections. These locations
|
||||
* can be read by programming tools (eg: Cypress Programmer, OpenOCD, pyOCD) to know that
|
||||
* there is a memory device attached and how to program it.
|
||||
* \} group_board_libs
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(CY_ENABLE_XIP_PROGRAM)
|
||||
|
||||
#include "cycfg_qspi_memslot.h"
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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, 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) */
|
||||
};
|
||||
|
||||
#endif /* defined(CY_ENABLE_XIP_PROGRAM) */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
|
@ -1,234 +0,0 @@
|
|||
/***************************************************************************//**
|
||||
* \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-2020 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))
|
||||
{
|
||||
cy_serial_flash_qspi_deinit();
|
||||
|
||||
if(CY_SMIF_SUCCESS != smifStatus)
|
||||
{
|
||||
result = (cy_rslt_t)smifStatus;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void cy_serial_flash_qspi_deinit(void)
|
||||
{
|
||||
if (qspi_obj.base != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
size_t cy_serial_flash_qspi_get_prog_size(uint32_t addr)
|
||||
{
|
||||
CY_UNUSED_PARAMETER(addr);
|
||||
return (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->programSize;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void cy_serial_flash_qspi_set_interrupt_priority(uint8_t priority)
|
||||
{
|
||||
NVIC_SetPriority(smif_interrupt_IRQn, priority);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CY_IP_MXSMIF */
|
||||
|
0
targets/TARGET_Cypress/TARGET_PSOC6/common/LICENSE → targets/TARGET_Cypress/TARGET_PSOC6/common/serial-flash/LICENSE
Normal file → Executable file
0
targets/TARGET_Cypress/TARGET_PSOC6/common/LICENSE → targets/TARGET_Cypress/TARGET_PSOC6/common/serial-flash/LICENSE
Normal file → Executable file
|
@ -0,0 +1,97 @@
|
|||
/***********************************************************************************************//**
|
||||
* \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-2021 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_board_libs
|
||||
* \{
|
||||
* In addition to the APIs for reading and writting to memory at runtime, this library also
|
||||
* provides support for informing programming tools about the external memory so it can be
|
||||
* be written at the same time as internal flash. This support can be enabled by defining
|
||||
* CY_ENABLE_XIP_PROGRAM while building the application. With this define in place, code
|
||||
* will be generated in the .cy_sflash_user_data & .cy_toc_part2 sections. These locations
|
||||
* can be read by programming tools (eg: Cypress Programmer, OpenOCD, pyOCD) to know that
|
||||
* there is a memory device attached and how to program it.
|
||||
* \} group_board_libs
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(CY_ENABLE_XIP_PROGRAM)
|
||||
|
||||
#include "cycfg_qspi_memslot.h"
|
||||
|
||||
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;
|
||||
|
||||
// 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, 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=0x01
|
||||
// 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)
|
||||
};
|
||||
|
||||
#endif // defined(CY_ENABLE_XIP_PROGRAM)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,868 @@
|
|||
/***********************************************************************************************//**
|
||||
* \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-2021 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_trigmux.h"
|
||||
#include "cy_dma.h"
|
||||
#include "cy_utils.h"
|
||||
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
#include <stdlib.h>
|
||||
#include "cyabs_rtos.h"
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
|
||||
#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 loops to run while polling the SMIF for its busy status. */
|
||||
#define SMIF_BUSY_CHECK_LOOP_COUNT (10lu)
|
||||
|
||||
/** Timeout to apply per loop while polling the SMIF for its busy status. */
|
||||
#define SMIF_BUSY_CHECK_TIMEOUT_MS (1lu) // in milliseconds
|
||||
|
||||
// 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)
|
||||
|
||||
/* Maximum number of bytes that can be read by SMIF in one transfer */
|
||||
#define SMIF_MAX_RX_COUNT (65536lu)
|
||||
|
||||
#define DMA_YCOUNT_ONE_LOOP (1lu)
|
||||
|
||||
#define MSB_SHIFT_EIGHT (0x08u)
|
||||
#define LSB_MASK (0xFFlu)
|
||||
|
||||
/* Masks used for checking the flag bits */
|
||||
#define FLAG_QSPI_HAL_INIT_DONE (0x01lu << 0)
|
||||
#define FLAG_DMA_INIT_DONE (0x01lu << 1)
|
||||
#define FLAG_READ_IN_PROGRESS (0x01lu << 2)
|
||||
|
||||
#define IS_FLAG_SET(mask) (status_flags & (mask))
|
||||
#define SET_FLAG(mask) (status_flags |= (mask))
|
||||
#define CLEAR_FLAG(mask) (status_flags &= ~(mask))
|
||||
|
||||
#if defined(CY_DEVICE_PSOC6ABLE2)
|
||||
/* You cannot simply change these values. The trigger mux connect code in
|
||||
* _init_dma() needs to be updated correspondingly.
|
||||
*/
|
||||
#define RX_DMA_INSTANCE DW1
|
||||
#define RX_DMA_CHANNEL_NUM (15lu)
|
||||
#define RX_DMA_CH0_IRQn (cpuss_interrupts_dw1_0_IRQn)
|
||||
#elif defined(CY_DEVICE_PSOC6A2M) || defined(CY_DEVICE_PSOC6A512K) || defined(CY_DEVICE_PSOC6256K)
|
||||
/* In these devices, only 1to1 triggers are available between SMIF and a
|
||||
* specific combination of DW instances and channel numbers.
|
||||
* i.e. TX trigger request from SMIF can connect only to DW1 CH22 and
|
||||
* RX trigger request from SMIF can connect only to DW1 CH23.
|
||||
*/
|
||||
#define RX_DMA_INSTANCE DW1
|
||||
#define RX_DMA_CHANNEL_NUM (23lu)
|
||||
#define RX_DMA_CH0_IRQn (cpuss_interrupts_dw1_0_IRQn)
|
||||
|
||||
#define DEVICE_GROUP_1TO1_TRIGGER
|
||||
#else // if defined(CY_DEVICE_PSOC6ABLE2)
|
||||
#define DMA_UNSUPPORTED
|
||||
#endif // if defined(CY_DEVICE_PSOC6ABLE2)
|
||||
|
||||
#define DMA_CHANNEL_PRIORITY (3lu)
|
||||
#define DMA_INTR_PRIORITY (7lu)
|
||||
|
||||
/** \endcond */
|
||||
|
||||
static cyhal_qspi_t qspi_obj;
|
||||
static volatile uint32_t status_flags;
|
||||
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
|
||||
};
|
||||
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
static cy_mutex_t serial_flash_mutex;
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
uint32_t addr;
|
||||
size_t length;
|
||||
uint8_t* buf;
|
||||
cy_serial_flash_qspi_read_complete_callback_t callback;
|
||||
void* callback_arg;
|
||||
} read_txfr_info_t;
|
||||
|
||||
static read_txfr_info_t read_txfr_info;
|
||||
|
||||
/* DMA related variables */
|
||||
static cy_stc_dma_descriptor_t dma_descr;
|
||||
|
||||
/* Default DW descriptor config */
|
||||
static cy_stc_dma_descriptor_config_t dma_descr_config =
|
||||
{
|
||||
.retrigger = CY_DMA_RETRIG_4CYC,
|
||||
.interruptType = CY_DMA_DESCR,
|
||||
.triggerOutType = CY_DMA_DESCR_CHAIN,
|
||||
.channelState = CY_DMA_CHANNEL_ENABLED,
|
||||
.triggerInType = CY_DMA_DESCR,
|
||||
.dataSize = CY_DMA_BYTE,
|
||||
.srcTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
|
||||
.dstTransferSize = CY_DMA_TRANSFER_SIZE_DATA,
|
||||
.descriptorType = CY_DMA_2D_TRANSFER,
|
||||
.srcAddress = 0,
|
||||
.dstAddress = 0,
|
||||
.srcXincrement = 0U,
|
||||
.dstXincrement = 1U,
|
||||
.xCount = 1UL,
|
||||
.srcYincrement = 0U,
|
||||
.dstYincrement = CY_DMA_LOOP_COUNT_MAX,
|
||||
.yCount = 1UL,
|
||||
.nextDescriptor = &dma_descr,
|
||||
};
|
||||
|
||||
/* Default DW channel config */
|
||||
static cy_stc_dma_channel_config_t dma_channel_config =
|
||||
{
|
||||
.descriptor = &dma_descr,
|
||||
.preemptable = false,
|
||||
.priority = DMA_CHANNEL_PRIORITY,
|
||||
.enable = false,
|
||||
.bufferable = false,
|
||||
};
|
||||
|
||||
static const cyhal_resource_inst_t DW_obj =
|
||||
{
|
||||
.type = CYHAL_RSC_DW,
|
||||
.block_num = ((uint32_t)RX_DMA_INSTANCE - DW0_BASE)/sizeof(DW_Type),
|
||||
.channel_num = RX_DMA_CHANNEL_NUM
|
||||
};
|
||||
|
||||
static cy_rslt_t _init_dma(void);
|
||||
static cy_rslt_t _deinit_dma(void);
|
||||
static void _rx_dma_irq_handler(void);
|
||||
static cy_en_smif_status_t _read_next_chunk(void);
|
||||
static void _value_to_byte_array(uint32_t value, uint8_t* byte_array, uint32_t start_pos,
|
||||
uint32_t size);
|
||||
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
|
||||
static inline cy_rslt_t _mutex_acquire(void);
|
||||
static inline cy_rslt_t _mutex_release(void);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_init
|
||||
//
|
||||
// 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 smif_status = 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)
|
||||
{
|
||||
SET_FLAG(FLAG_QSPI_HAL_INIT_DONE);
|
||||
|
||||
// Perform SFDP detection and XIP register configuration depending on the memory
|
||||
// configuration.
|
||||
smif_status = Cy_SMIF_MemInit(qspi_obj.base, &qspi_block_config, &qspi_obj.context);
|
||||
if (CY_SMIF_SUCCESS == smif_status)
|
||||
{
|
||||
// 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;
|
||||
smif_status =
|
||||
Cy_SMIF_MemIsQuadEnabled(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT],
|
||||
&isQuadEnabled, &qspi_obj.context);
|
||||
if ((CY_SMIF_SUCCESS == smif_status) && !isQuadEnabled)
|
||||
{
|
||||
smif_status =
|
||||
Cy_SMIF_MemEnableQuadMode(qspi_obj.base,
|
||||
qspi_block_config.memConfig[MEM_SLOT],
|
||||
CY_SERIAL_FLASH_QUAD_ENABLE_TIMEOUT_US,
|
||||
&qspi_obj.context);
|
||||
}
|
||||
|
||||
if (CY_SMIF_SUCCESS == smif_status)
|
||||
{
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
result = _init_dma();
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
SET_FLAG(FLAG_DMA_INIT_DONE);
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
/* Initialize the mutex */
|
||||
result = cy_rtos_init_mutex(&serial_flash_mutex);
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
}
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((CY_RSLT_SUCCESS != result) || (CY_SMIF_SUCCESS != smif_status))
|
||||
{
|
||||
cy_serial_flash_qspi_deinit();
|
||||
|
||||
if (CY_SMIF_SUCCESS != smif_status)
|
||||
{
|
||||
result = (cy_rslt_t)smif_status;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_deinit
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void cy_serial_flash_qspi_deinit(void)
|
||||
{
|
||||
cy_rslt_t result;
|
||||
|
||||
if (IS_FLAG_SET(FLAG_QSPI_HAL_INIT_DONE))
|
||||
{
|
||||
if (qspi_obj.base != NULL)
|
||||
{
|
||||
/* There is no harm in calling this even if Cy_SMIF_MemInit() did
|
||||
* not succeed since anyway we own the QSPI object.
|
||||
*/
|
||||
Cy_SMIF_MemDeInit(qspi_obj.base);
|
||||
}
|
||||
|
||||
cyhal_qspi_free(&qspi_obj);
|
||||
CLEAR_FLAG(FLAG_QSPI_HAL_INIT_DONE);
|
||||
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
if (IS_FLAG_SET(FLAG_DMA_INIT_DONE))
|
||||
{
|
||||
result = _deinit_dma();
|
||||
CY_ASSERT(CY_RSLT_SUCCESS == result);
|
||||
|
||||
CLEAR_FLAG(FLAG_DMA_INIT_DONE);
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
result = cy_rtos_deinit_mutex(&serial_flash_mutex);
|
||||
CY_ASSERT(CY_RSLT_SUCCESS == result);
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
}
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
}
|
||||
|
||||
CY_UNUSED_PARAMETER(result); /* To avoid compiler warning in Release mode. */
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_get_size
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t cy_serial_flash_qspi_get_size(void)
|
||||
{
|
||||
return (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->memSize;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_get_erase_size
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t cy_serial_flash_qspi_get_erase_size(uint32_t addr)
|
||||
{
|
||||
size_t erase_sector_size;
|
||||
cy_stc_smif_hybrid_region_info_t* hybrid_info = NULL;
|
||||
|
||||
cy_en_smif_status_t smif_status =
|
||||
Cy_SMIF_MemLocateHybridRegion(qspi_block_config.memConfig[MEM_SLOT], &hybrid_info, addr);
|
||||
|
||||
if (CY_SMIF_SUCCESS != smif_status)
|
||||
{
|
||||
erase_sector_size = (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->eraseSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
erase_sector_size = (size_t)hybrid_info->eraseSize;
|
||||
}
|
||||
|
||||
return erase_sector_size;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_get_prog_size
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t cy_serial_flash_qspi_get_prog_size(uint32_t addr)
|
||||
{
|
||||
CY_UNUSED_PARAMETER(addr);
|
||||
return (size_t)qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->programSize;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_read
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cy_rslt_t cy_serial_flash_qspi_read(uint32_t addr, size_t length, uint8_t* buf)
|
||||
{
|
||||
cy_rslt_t result_mutex_rel = CY_RSLT_SUCCESS;
|
||||
|
||||
cy_rslt_t result = _mutex_acquire();
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
// Cy_SMIF_MemRead() returns error if (addr + length) > total flash size.
|
||||
result = (cy_rslt_t)Cy_SMIF_MemRead(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT],
|
||||
addr,
|
||||
buf, length, &qspi_obj.context);
|
||||
result_mutex_rel = _mutex_release();
|
||||
}
|
||||
|
||||
/* Give priority to the status of SMIF operation when both SMIF operation
|
||||
* and mutex release fail.
|
||||
*/
|
||||
return ((CY_RSLT_SUCCESS == result) ? result_mutex_rel : result);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_abort_read
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cy_rslt_t cy_serial_flash_qspi_abort_read(void)
|
||||
{
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
cy_rslt_t result;
|
||||
|
||||
/* Wait until SMIF finishes any pending transfer. */
|
||||
for (uint32_t loop = 0; loop < SMIF_BUSY_CHECK_LOOP_COUNT; loop++)
|
||||
{
|
||||
if (!Cy_SMIF_BusyCheck(qspi_obj.base))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
cyhal_system_delay_ms(SMIF_BUSY_CHECK_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
if (Cy_SMIF_BusyCheck(qspi_obj.base))
|
||||
{
|
||||
SET_FLAG(FLAG_READ_IN_PROGRESS);
|
||||
result = CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cy_DMA_Channel_Disable(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
result = CY_RSLT_SUCCESS;
|
||||
CLEAR_FLAG(FLAG_READ_IN_PROGRESS);
|
||||
}
|
||||
|
||||
return result;
|
||||
#else // ifndef DMA_UNSUPPORTED
|
||||
return CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED;
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_read_async
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cy_rslt_t cy_serial_flash_qspi_read_async(uint32_t addr, size_t length, uint8_t* buf,
|
||||
cy_serial_flash_qspi_read_complete_callback_t callback,
|
||||
void* callback_arg)
|
||||
{
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
cy_rslt_t result = CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM;
|
||||
cy_rslt_t result_mutex_rel = CY_RSLT_SUCCESS;
|
||||
|
||||
CY_ASSERT(NULL != buf);
|
||||
|
||||
if (IS_FLAG_SET(FLAG_READ_IN_PROGRESS))
|
||||
{
|
||||
result = CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY; /* Previous read request is not yet complete.
|
||||
*/
|
||||
}
|
||||
else if ((addr + length) <= cy_serial_flash_qspi_get_size())
|
||||
{
|
||||
result = _mutex_acquire();
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
read_txfr_info.addr = addr;
|
||||
read_txfr_info.length = length;
|
||||
read_txfr_info.buf = buf;
|
||||
read_txfr_info.callback = callback;
|
||||
read_txfr_info.callback_arg = callback_arg;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
Cy_DMA_Channel_Enable(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
|
||||
SET_FLAG(FLAG_READ_IN_PROGRESS);
|
||||
result = (cy_rslt_t)_read_next_chunk(); /* Start the read transfer */
|
||||
|
||||
if (CY_RSLT_SUCCESS != result)
|
||||
{
|
||||
CLEAR_FLAG(FLAG_READ_IN_PROGRESS);
|
||||
}
|
||||
|
||||
result_mutex_rel = _mutex_release();
|
||||
}
|
||||
}
|
||||
|
||||
/* Give priority to the status of SMIF operation when both SMIF operation
|
||||
* and mutex release fail.
|
||||
*/
|
||||
return ((CY_RSLT_SUCCESS == result) ? result_mutex_rel : result);
|
||||
#else // ifndef DMA_UNSUPPORTED
|
||||
CY_UNUSED_PARAMETER(addr);
|
||||
CY_UNUSED_PARAMETER(length);
|
||||
CY_UNUSED_PARAMETER(buf);
|
||||
CY_UNUSED_PARAMETER(callback);
|
||||
CY_UNUSED_PARAMETER(callback_arg);
|
||||
|
||||
return CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED;
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_write
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cy_rslt_t cy_serial_flash_qspi_write(uint32_t addr, size_t length, const uint8_t* buf)
|
||||
{
|
||||
cy_rslt_t result_mutex_rel = CY_RSLT_SUCCESS;
|
||||
|
||||
cy_rslt_t result = _mutex_acquire();
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
// Cy_SMIF_MemWrite() returns error if (addr + length) > total flash size.
|
||||
result = (cy_rslt_t)Cy_SMIF_MemWrite(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT],
|
||||
addr,
|
||||
(uint8_t*)buf, length, &qspi_obj.context);
|
||||
result_mutex_rel = _mutex_release();
|
||||
}
|
||||
|
||||
/* Give priority to the status of SMIF operation when both SMIF operation
|
||||
* and mutex release fail.
|
||||
*/
|
||||
return ((CY_RSLT_SUCCESS == result) ? result_mutex_rel : result);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_erase
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cy_rslt_t cy_serial_flash_qspi_erase(uint32_t addr, size_t length)
|
||||
{
|
||||
cy_rslt_t result_mutex_rel = CY_RSLT_SUCCESS;
|
||||
|
||||
cy_rslt_t result = _mutex_acquire();
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
// If the erase is for the entire chip, use chip erase command
|
||||
if ((addr == 0u) && (length == cy_serial_flash_qspi_get_size()))
|
||||
{
|
||||
result =
|
||||
(cy_rslt_t)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.
|
||||
result =
|
||||
(cy_rslt_t)Cy_SMIF_MemEraseSector(qspi_obj.base,
|
||||
qspi_block_config.memConfig[MEM_SLOT],
|
||||
addr, length, &qspi_obj.context);
|
||||
}
|
||||
|
||||
result_mutex_rel = _mutex_release();
|
||||
}
|
||||
|
||||
/* Give priority to the status of SMIF operation when both SMIF operation
|
||||
* and mutex release fail.
|
||||
*/
|
||||
return ((CY_RSLT_SUCCESS == result) ? result_mutex_rel : result);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_enable_xip
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_set_interrupt_priority
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void cy_serial_flash_qspi_set_interrupt_priority(uint8_t priority)
|
||||
{
|
||||
NVIC_SetPriority(smif_interrupt_IRQn, priority);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// cy_serial_flash_qspi_set_interrupt_priority
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void cy_serial_flash_qspi_set_dma_interrupt_priority(uint8_t priority)
|
||||
{
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
NVIC_SetPriority((IRQn_Type)(RX_DMA_CH0_IRQn + RX_DMA_CHANNEL_NUM), priority);
|
||||
#else
|
||||
CY_UNUSED_PARAMETER(priority);
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
#ifndef DMA_UNSUPPORTED
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _read_next_chunk
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static cy_en_smif_status_t _read_next_chunk(void)
|
||||
{
|
||||
cy_en_smif_status_t smif_status = CY_SMIF_SUCCESS;
|
||||
uint32_t chunk;
|
||||
uint8_t addr_array[CY_SMIF_FOUR_BYTES_ADDR] = { 0U };
|
||||
|
||||
if (read_txfr_info.length > 0UL)
|
||||
{
|
||||
/* SMIF can read only up to 65536 bytes in one go. Split the larger read into multiple
|
||||
chunks */
|
||||
chunk =
|
||||
(read_txfr_info.length >
|
||||
SMIF_MAX_RX_COUNT) ? (SMIF_MAX_RX_COUNT) : read_txfr_info.length;
|
||||
|
||||
/* In 2D transfer, (X_count x Y_count) should be a multiple of CY_DMA_LOOP_COUNT_MAX (256).
|
||||
*/
|
||||
if (chunk > CY_DMA_LOOP_COUNT_MAX)
|
||||
{
|
||||
/* Make chunk divisible by CY_DMA_LOOP_COUNT_MAX (256) by masking out the LS bits */
|
||||
chunk &= ~(CY_DMA_LOOP_COUNT_MAX - 1);
|
||||
|
||||
dma_descr_config.yCount = chunk/CY_DMA_LOOP_COUNT_MAX;
|
||||
dma_descr_config.xCount = CY_DMA_LOOP_COUNT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_descr_config.yCount = DMA_YCOUNT_ONE_LOOP;
|
||||
dma_descr_config.xCount = chunk;
|
||||
}
|
||||
|
||||
dma_descr_config.dstAddress = (void*)read_txfr_info.buf;
|
||||
Cy_DMA_Descriptor_Init(&dma_descr, &dma_descr_config);
|
||||
|
||||
/* Pass NULL for buffer (and callback) so that the function does not
|
||||
* set up FIFO interrupt. We don't need FIFO interrupt to be setup
|
||||
* since we will be using DMA.
|
||||
*/
|
||||
_value_to_byte_array(read_txfr_info.addr, &addr_array[0], 0UL,
|
||||
qspi_block_config.memConfig[MEM_SLOT]->deviceCfg->numOfAddrBytes);
|
||||
smif_status = Cy_SMIF_MemCmdRead(qspi_obj.base, qspi_block_config.memConfig[MEM_SLOT],
|
||||
addr_array, NULL, chunk, NULL, &qspi_obj.context);
|
||||
|
||||
if (CY_SMIF_SUCCESS == smif_status)
|
||||
{
|
||||
/* Recalculate the next rxBuffer offset */
|
||||
read_txfr_info.length -= chunk;
|
||||
read_txfr_info.addr += chunk;
|
||||
read_txfr_info.buf += chunk;
|
||||
}
|
||||
}
|
||||
|
||||
return smif_status;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _init_dma
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static cy_rslt_t _init_dma(void)
|
||||
{
|
||||
cy_rslt_t result;
|
||||
|
||||
/* Set the source address of the descriptor */
|
||||
dma_descr_config.srcAddress = (void*)&SMIF_RX_DATA_FIFO_RD1(qspi_obj.base);
|
||||
|
||||
/* Configure the RX DMA */
|
||||
result =
|
||||
(cy_rslt_t)Cy_DMA_Channel_Init(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM, &dma_channel_config);
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
Cy_DMA_Channel_SetInterruptMask(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM, CY_DMA_INTR_MASK);
|
||||
Cy_DMA_Enable(RX_DMA_INSTANCE);
|
||||
|
||||
/* Configure interrupt for RX DMA */
|
||||
cy_stc_sysint_t dma_intr_config =
|
||||
{ .intrSrc = (IRQn_Type)(RX_DMA_CH0_IRQn + RX_DMA_CHANNEL_NUM),
|
||||
.intrPriority = DMA_INTR_PRIORITY };
|
||||
|
||||
result = (cy_rslt_t)Cy_SysInt_Init(&dma_intr_config, _rx_dma_irq_handler);
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
NVIC_EnableIRQ(dma_intr_config.intrSrc);
|
||||
|
||||
/* Configure the trigger mux */
|
||||
#if defined(DEVICE_GROUP_1TO1_TRIGGER)
|
||||
result = (cy_rslt_t)Cy_TrigMux_Select(TRIG_OUT_1TO1_3_SMIF_RX_TO_PDMA1_TR_IN23, false,
|
||||
TRIGGER_TYPE_LEVEL);
|
||||
#else
|
||||
result = (cy_rslt_t)Cy_TrigMux_Connect(TRIG13_IN_SMIF_TR_RX_REQ,
|
||||
TRIG13_OUT_TR_GROUP0_INPUT42, false,
|
||||
TRIGGER_TYPE_LEVEL);
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
result = (cy_rslt_t)Cy_TrigMux_Connect(TRIG1_IN_TR_GROUP13_OUTPUT15,
|
||||
TRIG1_OUT_CPUSS_DW1_TR_IN15, false,
|
||||
TRIGGER_TYPE_LEVEL);
|
||||
}
|
||||
#endif /* #if defined(DEVICE_GROUP_1TO1_TRIGGER) */
|
||||
}
|
||||
}
|
||||
|
||||
if (CY_RSLT_SUCCESS == result)
|
||||
{
|
||||
/* Reserve the DW instance so that HAL will not be able to use it later. */
|
||||
result = cyhal_hwmgr_reserve(&DW_obj);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _deinit_dma
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static cy_rslt_t _deinit_dma(void)
|
||||
{
|
||||
cy_rslt_t result = CY_RSLT_SUCCESS;
|
||||
|
||||
NVIC_DisableIRQ((IRQn_Type)(RX_DMA_CH0_IRQn + RX_DMA_CHANNEL_NUM));
|
||||
|
||||
/* Disable only the channel, not the DW instance as it may be used by other
|
||||
* part of the application.
|
||||
*/
|
||||
Cy_DMA_Channel_Disable(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
|
||||
/* Free the DMA resource so that HAL can use it now */
|
||||
cyhal_hwmgr_free(&DW_obj);
|
||||
|
||||
#if defined(DEVICE_GROUP_1TO1_TRIGGER)
|
||||
result = (cy_rslt_t)Cy_TrigMux_Deselect(TRIG_OUT_1TO1_3_SMIF_RX_TO_PDMA1_TR_IN23);
|
||||
#else
|
||||
/* No PDL function is available for handling deinit for non-1to1 trigger muxes. */
|
||||
#endif /* #if defined(DEVICE_GROUP_1TO1_TRIGGER) */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _rx_dma_irq_handler
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static void _rx_dma_irq_handler(void)
|
||||
{
|
||||
cy_en_smif_status_t smif_status = CY_SMIF_SUCCESS;
|
||||
bool terminate_read_txfr = true;
|
||||
cy_en_dma_intr_cause_t cause = Cy_DMA_Channel_GetStatus(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
|
||||
Cy_DMA_Channel_ClearInterrupt(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
|
||||
if (CY_DMA_INTR_CAUSE_COMPLETION == cause)
|
||||
{
|
||||
if (read_txfr_info.length > 0UL)
|
||||
{
|
||||
smif_status = _read_next_chunk();
|
||||
|
||||
if (CY_SMIF_SUCCESS == smif_status)
|
||||
{
|
||||
terminate_read_txfr = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
smif_status = (cy_en_smif_status_t)CY_RSLT_SERIAL_FLASH_ERR_DMA;
|
||||
}
|
||||
|
||||
if (terminate_read_txfr)
|
||||
{
|
||||
Cy_DMA_Channel_Disable(RX_DMA_INSTANCE, RX_DMA_CHANNEL_NUM);
|
||||
CLEAR_FLAG(FLAG_READ_IN_PROGRESS);
|
||||
|
||||
/* Execute the callback */
|
||||
if (NULL != read_txfr_info.callback)
|
||||
{
|
||||
read_txfr_info.callback((cy_rslt_t)smif_status, read_txfr_info.callback_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: _value_to_byte_array
|
||||
****************************************************************************//**
|
||||
*
|
||||
* Unpacks the specified number of bytes from a 32-bit value into the given byte
|
||||
* array.
|
||||
*
|
||||
* \param value
|
||||
* The 32-bit (4-byte) value to unpack.
|
||||
*
|
||||
* \param byte_array
|
||||
* The byte array to fill.
|
||||
*
|
||||
* \param start_pos
|
||||
* The start position of the byte array to begin filling from.
|
||||
*
|
||||
* \param size
|
||||
* The number of bytes to unpack.
|
||||
*
|
||||
*******************************************************************************/
|
||||
static void _value_to_byte_array(uint32_t value, uint8_t* byte_array, uint32_t start_pos,
|
||||
uint32_t size)
|
||||
{
|
||||
CY_ASSERT((0lu < size) && (CY_SMIF_FOUR_BYTES_ADDR >= size));
|
||||
CY_ASSERT(NULL != byte_array);
|
||||
|
||||
do
|
||||
{
|
||||
size--;
|
||||
byte_array[size + start_pos] = (uint8_t)(value & LSB_MASK);
|
||||
value >>= MSB_SHIFT_EIGHT; /* Shift to get the next byte */
|
||||
} while (size > 0U);
|
||||
}
|
||||
|
||||
|
||||
#endif /* #ifndef DMA_UNSUPPORTED */
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _mutex_acquire
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static inline cy_rslt_t _mutex_acquire(void)
|
||||
{
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
return cy_rtos_get_mutex(&serial_flash_mutex, CY_RTOS_NEVER_TIMEOUT);
|
||||
#else
|
||||
return CY_RSLT_SUCCESS;
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// _mutex_release
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static inline cy_rslt_t _mutex_release(void)
|
||||
{
|
||||
#if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE)
|
||||
return cy_rtos_set_mutex(&serial_flash_mutex);
|
||||
#else
|
||||
return CY_RSLT_SUCCESS;
|
||||
#endif /* #if defined(CY_SERIAL_FLASH_QSPI_THREAD_SAFE) */
|
||||
}
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CY_IP_MXSMIF
|
|
@ -1,33 +1,45 @@
|
|||
/***************************************************************************//**
|
||||
* \file cy_serial_flash_qspi.h
|
||||
*
|
||||
* \brief
|
||||
* Provides APIs for interacting with an external flash connected to the SPI or
|
||||
* QSPI interface. Flash operations read, write, and erase are implemented as
|
||||
* blocking functions.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2018-2020 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.
|
||||
*******************************************************************************/
|
||||
/***********************************************************************************************//**
|
||||
* \file cy_serial_flash_qspi.h
|
||||
*
|
||||
* \brief
|
||||
* Provides APIs for interacting with an external flash connected to the SPI or
|
||||
* QSPI interface. Read is implemented as both blocking and non-blocking whereas
|
||||
* write, and erase are implemented as blocking functions.
|
||||
*
|
||||
***************************************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2018-2021 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_board_libs Serial Flash
|
||||
* \{
|
||||
*/
|
||||
* \addtogroup group_board_libs Serial Flash
|
||||
* \ingroup group_lib
|
||||
* \{
|
||||
*
|
||||
* \section section_resource_usage DMA Resource Usage
|
||||
* This library uses fixed DMA (Datawire or DW) resources and supports DMA only
|
||||
* for the following devices. DMA is not supported for other devices and the
|
||||
* functions \ref cy_serial_flash_qspi_read_async() and
|
||||
* \ref cy_serial_flash_qspi_abort_read() will return
|
||||
* \ref CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED error and
|
||||
* \ref cy_serial_flash_qspi_set_dma_interrupt_priority() will simply return
|
||||
* doing nothing.
|
||||
* * CY8C6xx4, CY8C6xx5, CY8C6xx8, CY8C6xxA, CYB06xx5, CYB06xxA, CYS06xxA: <b>DW1, Channel 23</b>
|
||||
* * CY8C6xx6, CY8C6xx7, CYB06xx7: <b>DW1, Channel 15</b>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -43,7 +55,37 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/** The function or operation is not supported on the target or the memory */
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 1))
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_UNSUPPORTED \
|
||||
(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 1))
|
||||
|
||||
/** Parameters passed to a function are invalid */
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_BAD_PARAM \
|
||||
(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 2))
|
||||
|
||||
/** A previously initiated read operation is not yet complete */
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_READ_BUSY \
|
||||
(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 3))
|
||||
|
||||
/** A DMA error occurred during read transfer */
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_DMA \
|
||||
(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 4))
|
||||
|
||||
/** Read abort failed. QSPI block is busy. */
|
||||
#define CY_RSLT_SERIAL_FLASH_ERR_QSPI_BUSY \
|
||||
(CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_FLASH, 5))
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/** Enables thread-safety for use with multi-threaded RTOS environment. */
|
||||
#define CY_SERIAL_FLASH_QSPI_THREAD_SAFE
|
||||
#endif /* #ifdef DOXYGEN */
|
||||
|
||||
/**
|
||||
* Callback pointer to use with \ref cy_serial_flash_qspi_read_async().
|
||||
* \param peration_status Status of the read operation
|
||||
* \param callback_arg Pointer to be passed back to the callback function
|
||||
*/
|
||||
typedef void (* cy_serial_flash_qspi_read_complete_callback_t)(cy_rslt_t operation_status,
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* \brief Initializes the serial flash memory. This function accepts up to 8
|
||||
|
@ -84,6 +126,10 @@ cy_rslt_t cy_serial_flash_qspi_init(
|
|||
|
||||
/**
|
||||
* \brief De-initializes the serial flash memory.
|
||||
* Before calling this function, ensure that an ongoing asynchronous read
|
||||
* operation is either completed or successfully aborted.
|
||||
* Async read is started by calling \ref cy_serial_flash_qspi_read_async() and
|
||||
* aborted by calling \ref cy_serial_flash_qspi_abort_read().
|
||||
*/
|
||||
void cy_serial_flash_qspi_deinit(void);
|
||||
|
||||
|
@ -120,6 +166,7 @@ __STATIC_INLINE uint32_t cy_serial_flash_get_sector_start_address(uint32_t addr)
|
|||
return (addr & ~(cy_serial_flash_qspi_get_erase_size(addr) - 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Reads data from the serial flash memory. This is a blocking
|
||||
* function. Returns error if (addr + length) exceeds the flash size.
|
||||
|
@ -128,7 +175,34 @@ __STATIC_INLINE uint32_t cy_serial_flash_get_sector_start_address(uint32_t addr)
|
|||
* \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.
|
||||
*/
|
||||
cy_rslt_t cy_serial_flash_qspi_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 Reads data from the serial flash memory. This is a non-blocking
|
||||
* function. Returns error if (addr + length) exceeds the flash size.
|
||||
* Uses fixed DMA (DW) instance and channel for transferring the data from
|
||||
* QSPI RX FIFO to the user-provided buffer.
|
||||
* \param addr Starting address to read from
|
||||
* \param length Number of data bytes to read
|
||||
* \param buf Pointer to the buffer to store the data read from the memory
|
||||
* \param callback Pointer to the callback function to be called after the read
|
||||
* operation is complete. Callback is invoked from the DMA ISR.
|
||||
* \param callback_arg Pointer to the argument to be passed to the callback
|
||||
* function
|
||||
* \returns CY_RSLT_SUCCESS if the read was successful, an error code otherwise.
|
||||
*/
|
||||
cy_rslt_t cy_serial_flash_qspi_read_async(uint32_t addr, size_t length, uint8_t* buf,
|
||||
cy_serial_flash_qspi_read_complete_callback_t callback,
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* \brief Aborts an ongoing asynchronous read initiated by calling
|
||||
* \ref cy_serial_flash_qspi_read_async().
|
||||
*
|
||||
* \returns CY_RSLT_SUCCESS if the abort was successful, an error code
|
||||
* if the QSPI block is still busy after a timeout.
|
||||
*/
|
||||
cy_rslt_t cy_serial_flash_qspi_abort_read(void);
|
||||
|
||||
/**
|
||||
* \brief Writes the data to the serial flash memory. The program area
|
||||
|
@ -141,13 +215,16 @@ cy_rslt_t cy_serial_flash_qspi_read(uint32_t addr, size_t length, uint8_t *buf);
|
|||
* \returns CY_RSLT_SUCCESS if the write was successful, an error code
|
||||
* otherwise.
|
||||
*/
|
||||
cy_rslt_t cy_serial_flash_qspi_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 memory, uses chip erase command when
|
||||
* 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
|
||||
* to the sector size or if (addr + length) exceeds the flash size.
|
||||
* For memories with hybrid sectors, returns error if the end address
|
||||
* (=addr + length) is not aligned to the size of the sector in which the end
|
||||
* address is located.
|
||||
* Call \ref cy_serial_flash_qspi_get_size() to get the flash size and
|
||||
* call \ref cy_serial_flash_qspi_get_erase_size() to get the size of an erase
|
||||
* sector.
|
||||
|
@ -177,10 +254,17 @@ cy_rslt_t cy_serial_flash_qspi_enable_xip(bool enable);
|
|||
*/
|
||||
void cy_serial_flash_qspi_set_interrupt_priority(uint8_t priority);
|
||||
|
||||
/**
|
||||
* \brief Changes the DMA interrupt priority
|
||||
* \param priority interrupt priority to be set
|
||||
*/
|
||||
void cy_serial_flash_qspi_set_dma_interrupt_priority(uint8_t priority);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CY_IP_MXSMIF */
|
||||
#endif // CY_IP_MXSMIF
|
||||
|
||||
/** \} group_board_libs */
|
|
@ -0,0 +1 @@
|
|||
<version>1.1.0.20805</version>
|
|
@ -1 +0,0 @@
|
|||
<version>.19214</version>
|
Loading…
Reference in New Issue