Skip to content
Permalink
4b3d85f0fd
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
381 lines (330 sloc) 13.4 KB
/***************************************************************************//**
* \file cybsp_smif_init.c
*
* Description:
* Provides initialization code for SMIF.
*
********************************************************************************
* \copyright
* Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of 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.
*******************************************************************************/
#if CY_PDL_FLASH_BOOT
#include "cybsp_smif_init.h"
#include "cycfg_pins.h"
#include "cyhal_pin_package.h"
cy_stc_smif_context_t cybsp_smif_context;
static uint32_t SMIF_PORT_SEL0;
static uint32_t SMIF_PORT_SEL1;
static uint32_t SMIF_CFG;
static uint32_t SMIF_OUT;
/*******************************************************************************
* Function Name: smif_disable
****************************************************************************//**
*
* it disable the the SMIF.
*
* \return NULL.
*
*******************************************************************************/
CY_RAMFUNC_BEGIN
void cybsp_smif_disable()
{
// to minimize DeepSleep latency this code assumes that all of the SMIF pins are on the same
// port
int port_number= CYHAL_GET_PORT(CYBSP_QSPI_SS);
SMIF0->CTL = SMIF0->CTL & ~SMIF_CTL_ENABLED_Msk;
SMIF_PORT_SEL0 = ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0;
SMIF_PORT_SEL1 = ((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1;
SMIF_CFG = ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG;
SMIF_OUT = ((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT;
((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0 = 0x00;
((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1 = 0x00;
((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG = 0x600006;
((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT = 0x1;
}
CY_RAMFUNC_END
/*******************************************************************************
* Function Name: smif_enable
****************************************************************************//**
*
* it enable the the SMIF.
*
* \return NULL.
*
*******************************************************************************/
CY_RAMFUNC_BEGIN
void cybsp_smif_enable()
{
int port_number= CYHAL_GET_PORT(CYBSP_QSPI_SS);
SMIF0->CTL = SMIF0->CTL | SMIF_CTL_ENABLED_Msk;
((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL0 = SMIF_PORT_SEL0;
((HSIOM_PRT_Type*)&HSIOM->PRT[port_number])->PORT_SEL1 = SMIF_PORT_SEL1;
((GPIO_PRT_Type*)&GPIO->PRT[port_number])->CFG = SMIF_CFG;
((GPIO_PRT_Type*)&GPIO->PRT[port_number])->OUT = SMIF_OUT;
}
CY_RAMFUNC_END
/*******************************************************************************
* Function Name: cybsp_is_memory_ready
****************************************************************************//**
*
* Polls the memory device to check whether it is ready to accept new commands or
* not until either it is ready or the retries have exceeded the limit.
*
* \param memConfig
* memory device configuration
*
* \return Status of the operation.
* CY_SMIF_SUCCESS - Memory is ready to accept new commands.
* CY_SMIF_EXCEED_TIMEOUT - Memory is busy.
*
*******************************************************************************/
#if defined (__ICCARM__)
/* Suppress warnings originating from configurator */
/* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
CY_PRAGMA(diag_suppress = Ta022)
#endif
//--------------------------------------------------------------------------------------------------
// cybsp_is_memory_ready
//--------------------------------------------------------------------------------------------------
CY_RAMFUNC_BEGIN
cy_en_smif_status_t cybsp_is_memory_ready(cy_stc_smif_mem_config_t const* memConfig)
{
uint32_t retries = 0;
bool isBusy;
do
{
isBusy =
Cy_SMIF_Memslot_IsBusy(SMIF_HW, (cy_stc_smif_mem_config_t*)memConfig,
&cybsp_smif_context);
Cy_SysLib_DelayUs(15);
retries++;
} while(isBusy && (retries < MEMORY_BUSY_CHECK_RETRIES));
return (isBusy ? CY_SMIF_EXCEED_TIMEOUT : CY_SMIF_SUCCESS);
}
CY_RAMFUNC_END
#if defined (__ICCARM__)
CY_PRAGMA(diag_default = Ta022)
#endif
/*******************************************************************************
* Function Name: cybsp_enable_quad_mode
****************************************************************************//*
*
* This function sets the QE (QUAD Enable) bit in the external memory
* configuration register to enable Quad SPI mode.
*
* \param memConfig
* Memory device configuration
*
* \return Status of the operation. See cy_en_smif_status_t.
*
*******************************************************************************/
#if defined (__ICCARM__)
/* Suppress warnings originating from configurator */
/* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
CY_PRAGMA(diag_suppress = Ta022)
#endif
//--------------------------------------------------------------------------------------------------
// cybsp_enable_quad_mode
//--------------------------------------------------------------------------------------------------
CY_RAMFUNC_BEGIN
cy_en_smif_status_t cybsp_enable_quad_mode(cy_stc_smif_mem_config_t const* memConfig)
{
cy_en_smif_status_t status;
/* Send Write Enable to external memory */
status = Cy_SMIF_Memslot_CmdWriteEnable(SMIF_HW, smifMemConfigs[0], &cybsp_smif_context);
if (CY_SMIF_SUCCESS == status)
{
status = Cy_SMIF_Memslot_QuadEnable(SMIF_HW, (cy_stc_smif_mem_config_t*)memConfig,
&cybsp_smif_context);
if (CY_SMIF_SUCCESS == status)
{
/* Poll memory for the completion of operation */
status = cybsp_is_memory_ready(memConfig);
}
}
return status;
}
CY_RAMFUNC_END
#if defined (__ICCARM__)
CY_PRAGMA(diag_default = Ta022)
#endif
/*******************************************************************************
* Function Name: cybsp_is_quad_enabled
****************************************************************************//**
*
* Checks whether QE (Quad Enable) bit is set or not in the configuration
* register of the memory.
*
* \param memConfig
* Memory device configuration
*
* \param isQuadEnabled
* This parameter is updated to indicate whether Quad mode is enabled (true) or
* not (false). The value is valid only when the function returns
* CY_SMIF_SUCCESS.
*
* \return Status of the operation. See cy_en_smif_status_t.
*
*******************************************************************************/
#if defined (__ICCARM__)
/* Suppress warnings originating from configurator */
/* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
CY_PRAGMA(diag_suppress = Ta022)
#endif
//--------------------------------------------------------------------------------------------------
// cybsp_is_quad_enabled
//--------------------------------------------------------------------------------------------------
CY_RAMFUNC_BEGIN
cy_en_smif_status_t cybsp_is_quad_enabled(cy_stc_smif_mem_config_t const* memConfig,
bool* isQuadEnabled)
{
cy_en_smif_status_t status;
uint8_t readStatus = 0;
uint32_t statusCmd = memConfig->deviceCfg->readStsRegQeCmd->command;
uint8_t maskQE = (uint8_t)memConfig->deviceCfg->stsRegQuadEnableMask;
status = Cy_SMIF_Memslot_CmdReadSts(SMIF_HW, memConfig, &readStatus, statusCmd,
&cybsp_smif_context);
*isQuadEnabled = false;
if (CY_SMIF_SUCCESS == status)
{
/* Check whether Quad mode is already enabled or not */
*isQuadEnabled = (maskQE == (readStatus & maskQE));
}
return status;
}
CY_RAMFUNC_END
#if defined (__ICCARM__)
CY_PRAGMA(diag_default = Ta022)
#endif
cy_stc_smif_config_t cybsp_smif_config =
{
.mode = (uint32_t)CY_SMIF_NORMAL,
.deselectDelay = 7,
.rxClockSel = (uint32_t)CY_SMIF_SEL_INVERTED_FEEDBACK_CLK,
.blockEvent = (uint32_t)CY_SMIF_BUS_ERROR,
};
/********************************************************
* cybsp_smif_start
*********************************************************
* Initializes the SMIF hardware, sets the slave select
* and enables the SMIF block.
*
* returns: the status of the block during initialization
*
********************************************************/
#if defined (__ICCARM__)
/* Suppress warnings originating from configurator */
/* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
CY_PRAGMA(diag_suppress = Ta022)
#endif
//--------------------------------------------------------------------------------------------------
// cybsp_smif_start
//--------------------------------------------------------------------------------------------------
CY_RAMFUNC_BEGIN
cy_en_smif_status_t cybsp_smif_start(void)
{
cy_en_smif_status_t cybsp_smif_status = CY_SMIF_BAD_PARAM;
cybsp_smif_status =
Cy_SMIF_Init(SMIF_HW, &cybsp_smif_config, TIMEOUT_1_MS, &cybsp_smif_context);
if (cybsp_smif_status == CY_SMIF_SUCCESS)
{
Cy_SMIF_SetDataSelect(SMIF_HW, smifMemConfigs[0]->slaveSelect,
smifMemConfigs[0]->dataSelect);
Cy_SMIF_Enable(SMIF_HW, &cybsp_smif_context);
}
return cybsp_smif_status;
}
CY_RAMFUNC_END
#if defined (__ICCARM__)
CY_PRAGMA(diag_default = Ta022)
#endif
/********************************************************
* cybsp_smif_init
*********************************************************
* Configures the SMIF hardware
********************************************************/
#if defined (__ICCARM__)
/* Suppress warnings originating from configurator */
/* Ta022 : "Call to a non __ramfunc function from within a __ramfunc function" */
CY_PRAGMA(diag_suppress = Ta022)
#endif
//--------------------------------------------------------------------------------------------------
// cybsp_smif_init
//--------------------------------------------------------------------------------------------------
CY_RAMFUNC_BEGIN
cy_en_smif_status_t cybsp_smif_init(void)
{
/* Initalization Status Holders */
cy_en_smif_status_t cybsp_smif_status = CY_SMIF_BAD_PARAM;
bool QE_status = false;
cybsp_smif_status = cybsp_smif_start();
if (cybsp_smif_status == CY_SMIF_SUCCESS)
{
cybsp_smif_status = Cy_SMIF_MemCmdReleasePowerDown(SMIF0,
smifMemConfigs[0],
&cybsp_smif_context);
if (CY_SMIF_SUCCESS == cybsp_smif_status)
{
cybsp_smif_status = cybsp_is_memory_ready(smifMemConfigs[0]);
if (CY_SMIF_SUCCESS == cybsp_smif_status)
{
/* Map memory device to memory map */
cybsp_smif_status = Cy_SMIF_Memslot_Init(SMIF_HW,
(cy_stc_smif_block_config_t*)&smifBlockConfig,
&cybsp_smif_context);
if (cybsp_smif_status == CY_SMIF_SUCCESS)
{
/* Even after SFDP enumeration QE command is not initialised */
/* So, it should be 1.0 device */
if ((smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command ==
CY_SMIF_NO_COMMAND_OR_MODE) ||
(smifMemConfigs[0]->deviceCfg->readStsRegQeCmd->command == 0))
{
cybsp_smif_status = Cy_SMIF_MemInitSfdpMode(SMIF_HW,
smifMemConfigs[0],
CY_SMIF_WIDTH_QUAD,
CY_SMIF_SFDP_QER_1,
&cybsp_smif_context);
}
if (cybsp_smif_status == CY_SMIF_SUCCESS)
{
/* Check if Quad mode is already enabled */
cybsp_is_quad_enabled(smifMemConfigs[0], &QE_status);
/* If not enabled, enable quad mode */
if (!QE_status)
{
/* Enable Quad mode */
cybsp_smif_status = cybsp_enable_quad_mode(smifMemConfigs[0]);
}
if (cybsp_smif_status == CY_SMIF_SUCCESS)
{
/* Put the device in XIP mode */
Cy_SMIF_SetMode(SMIF_HW, CY_SMIF_MEMORY);
}
}
}
}
}
}
return cybsp_smif_status;
}
CY_RAMFUNC_END
#if defined (__ICCARM__)
CY_PRAGMA(diag_default = Ta022)
#endif
#endif // if CY_PDL_FLASH_BOOT