renesas-tb-s1ja: implement hal_flash_bank_synergy

This commit is contained in:
Matthias Ringwald 2020-02-25 14:04:31 +01:00
parent 78764d994a
commit b1a0b198f1
17 changed files with 5076 additions and 2 deletions

View File

@ -187,9 +187,9 @@
<v1:configSetting configurationId="p304.gpio_mode" altId="p304.gpio_mode.gpio_mode_in"/>
<v1:configSetting configurationId="p303.gpio_mode" altId="p303.gpio_mode.gpio_mode_out.high"/>
<v1:configSetting configurationId="p304" altId="p304.input"/>
<v1:configSetting configurationId="p303" altId="p303.output.high"></v1:configSetting>
<v1:configSetting configurationId="p303" altId="p303.output.high"/>
<v1:configSetting configurationId="sci0.sck" altId="sci0.sck.none"/>
<v1:configSetting configurationId="sci0.cts" altId="sci0.cts.none"></v1:configSetting>
<v1:configSetting configurationId="sci0.cts" altId="sci0.cts.none"/>
<v1:configSetting configurationId="p112.gpio_mode" altId="p112.gpio_mode.gpio_mode_out.low"/>
<v1:configSetting configurationId="p112" altId="p112.output.low"/>
<v1:propertySetting propertyId="p112.symbolic_name" value="nShutdown"/>

View File

@ -154,6 +154,10 @@
<description>General Purpose Timer: Provides=[Timer ,GPT]</description>
<originalPack>Renesas.Synergy.1.7.5.pack</originalPack>
</component>
<component apiversion="" class="HAL Drivers" condition="" group="all" subgroup="r_flash_lp" variant="" vendor="Renesas" version="1.7.5">
<description>Flash Memory: Provides=[Flash]</description>
<originalPack>Renesas.Synergy.1.7.5.pack</originalPack>
</component>
</synergyComponentSelection>
<synergyIcuConfiguration/>
<synergyMessagingConfiguration/>
@ -247,6 +251,12 @@
<property id="module.driver.timer.p_callback" value="timer_1ms"/>
<property id="module.driver.timer.irq_ipl" value="board.icu.common.irq.priority3"/>
</module>
<module id="module.driver.flash_on_flash_lp.182111309">
<property id="module.driver.flash.name" value="g_flash0"/>
<property id="module.driver.flash.data_flash_bgo" value="module.driver.flash.data_flash_bgo.disabled"/>
<property id="module.driver.flash.p_callback" value="NULL"/>
<property id="module.driver.flash.irq_ipl" value="board.icu.common.irq.disabled"/>
</module>
<context id="_hal.0">
<stack module="module.driver.elc_on_elc.0"/>
<stack module="module.driver.cgc_on_cgc.0"/>
@ -257,6 +267,7 @@
<stack module="module.driver.transfer_on_dtc.1089663038" requires="module.driver.uart_on_sci_uart.requires.transfer_rx"/>
</stack>
<stack module="module.driver.timer_on_gpt.445970172"/>
<stack module="module.driver.flash_on_flash_lp.182111309"/>
</context>
<config id="config.driver.cgc">
<property id="config.driver.cgc.param_checking_enable" value="config.driver.cgc.param_checking_enable.bsp"/>
@ -269,6 +280,10 @@
<config id="config.driver.ioport">
<property id="config.driver.ioport.checking" value="config.driver.ioport.checking.system"/>
</config>
<config id="config.driver.flash_lp">
<property id="config.driver.flash_lp.param_checking_enable" value="config.driver.flash_lp.param_checking_enable.bsp"/>
<property id="config.driver.flash_lp.param_code_flash_programming_enable" value="config.driver.flash_lp.param_code_flash_programming_enable.disabled"/>
</config>
<config id="config.driver.sci_uart">
<property id="config.driver.sci_uart.external_rts_operation" value="config.driver.sci_uart.external_rts_operation.disabled"/>
<property id="config.driver.sci_uart.uart_rx_enable" value="config.driver.sci_uart.uart_rx_enable.enabled"/>

View File

@ -0,0 +1,383 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : r_flash_api.h
* Description : API Interface for the FLASH peripheral on SC32 MCUs.
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @ingroup Interface_Library
* @defgroup FLASH_API Flash Interface
* @brief Interface for the flash controller.
*
* @section FLASH_API_SUMMARY Summary
* The Flash interface provides the functionality necessary to read, write, erase and blank check the
* Flash memory. Additionally functions are provided to configure the access window and swap areas of the
* flash memory.
*
* Implemented by:
* - @ref FLASH_HP
* - @ref FLASH
*
* Related SSP architecture topics:
* - @ref ssp-interfaces
* - @ref ssp-predefined-layers
* - @ref using-ssp-modules
*
* Flash Interface description: @ref ModuleFlash
*
*
* @{
**********************************************************************************************************************/
#ifndef DRV_FLASH_API_H
#define DRV_FLASH_API_H
/***********************************************************************************************************************
* Includes
**********************************************************************************************************************/
/* Register definitions, common services and error codes. */
#include "bsp_api.h"
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/**********************************************************************************************************************
* Macro definitions
*********************************************************************************************************************/
#define FLASH_API_VERSION_MAJOR (1U) /**< FLASH HAL API version number (Major) */
#define FLASH_API_VERSION_MINOR (5U) /**< FLASH HAL API version number (Minor) */
/*********************************************************************************************************************
* Typedef definitions
*********************************************************************************************************************/
/** Result type for certain operations */
typedef enum e_flash_result
{
FLASH_RESULT_BLANK, ///< Return status for Blank Check Function
FLASH_RESULT_NOT_BLANK, ///< Return status for Blank Check Function
FLASH_RESULT_BGO_ACTIVE ///< Flash is configured for BGO mode. Result is returned in callback.
} flash_result_t;
/** Parameter for specifying the startup area swap being requested by startupAreaSelect() */
typedef enum e_flash_startup_area_swap
{
FLASH_STARTUP_AREA_BLOCK1 = 0, ///< Startup area will be set to Block 1
FLASH_STARTUP_AREA_BLOCK0, ///< Startup area will be set to Block 0
FLASH_STARTUP_AREA_BTFLG ///< Startup area will be set based on the value of the BTFLG
} flash_startup_area_swap_t;
/** Event types returned by the ISR callback when used in Data Flash BGO mode */
typedef enum e_flash_event
{
FLASH_EVENT_ERASE_COMPLETE, ///< Erase operation successfully completed
FLASH_EVENT_WRITE_COMPLETE, ///< Write operation successfully completed
FLASH_EVENT_BLANK, ///< Blank check operation successfully completed. Specified area is blank
FLASH_EVENT_NOT_BLANK, ///< Blank check operation successfully completed. Specified area is NOT blank
FLASH_EVENT_ERR_DF_ACCESS, ///< Data Flash operation failed. Can occur when writing an unerased section.
FLASH_EVENT_ERR_CF_ACCESS, ///< Code Flash operation failed. Can occur when writing an unerased section.
FLASH_EVENT_ERR_CMD_LOCKED, ///< Operation failed, FCU is in Locked state (often result of an illegal command)
FLASH_EVENT_ERR_FAILURE, ///< Erase or Program Operation failed
FLASH_EVENT_ERR_ONE_BIT ///< A 1-bit error has been corrected when reading the flash memory area by the sequencer.
} flash_event_t;
/** ID Code Modes for writing to ID code registers */
typedef enum e_flash_id_code_mode
{
FLASH_ID_CODE_MODE_UNLOCKED, ///< ID code is ignored
FLASH_ID_CODE_MODE_LOCKED_WITH_ALL_ERASE_SUPPORT, ///< ID code is checked. All erase is available.
FLASH_ID_CODE_MODE_LOCKED ///< ID code is checked.
} flash_id_code_mode_t;
/** Flash block details stored in factory flash. */
typedef struct st_flash_fmi_block_info
{
uint32_t block_section_st_addr; ///< starting address for this block section (blocks of this size)
uint32_t block_section_end_addr; ///< ending address for this block section (blocks of this size)
uint32_t block_size; ///< Flash erase block size
uint32_t block_size_write; ///< Flash write block size
} flash_fmi_block_info_t;
/** Flash block details */
typedef struct st_flash_fmi_regions
{
uint32_t num_regions; ///< Length of block info array
flash_fmi_block_info_t const * p_block_array; ///< Block info array base address
} flash_fmi_regions_t;
/** Information about the flash blocks */
typedef struct st_flash_info
{
flash_fmi_regions_t code_flash; ///< Information about the code flash regions
flash_fmi_regions_t data_flash; ///< Information about the code flash regions
}flash_info_t;
/** Flash control block. Allocate an instance specific control block to pass into the flash API calls.
* @par Implemented as
* - flash_lp_instance_ctrl_t
* - flash_hp_instance_ctrl_t
*/
typedef void flash_ctrl_t;
/** Callback function parameter data */
typedef struct st_flash_user_cb_data
{
flash_event_t event; ///< Event can be used to identify what caused the callback (flash ready or error).
void const * p_context; ///< Placeholder for user data. Set in flash_api_t::open function in::flash_cfg_t.
} flash_callback_args_t;
/** FLASH Configuration */
typedef struct st_flash_cfg
{
bool data_flash_bgo; ///< True if BGO (Background Operation) is enabled for Data Flash.
/* Configuration for FLASH Event processing */
void (* p_callback)(flash_callback_args_t * p_args); ///< Callback provided when a Flash interrupt ISR occurs.
/* Pointer to FLASH peripheral specific configuration */
void const * p_extend; ///< FLASH hardware dependent configuration
void const * p_context; ///< Placeholder for user data. Passed to user callback in ::flash_callback_args_t.
uint8_t irq_ipl; ///< Flash ready interrupt priority
uint8_t err_irq_ipl; ///< Flash error interrupt priority (unused in r_flash_lp)
} flash_cfg_t;
/** Shared Interface definition for FLASH */
typedef struct st_flash_api
{
/** Open FLASH device.
* @par Implemented as
* - R_FLASH_LP_Open()
* - R_FLASH_HP_Open()
*
* @param[out] p_ctrl Pointer to FLASH device control. Must be declared by user. Value set here.
* @param[in] flash_cfg_t Pointer to FLASH configuration structure. All elements of this structure
* must be set by the user.
*/
ssp_err_t (* open)(flash_ctrl_t * const p_ctrl,
flash_cfg_t const * const p_cfg);
/** Write FLASH device.
* @par Implemented as
* - R_FLASH_LP_Write()
* - R_FLASH_HP_Write()
*
* @param[in] p_ctrl Control for the FLASH device context.
* @param[in] src_address Address of the buffer containing the data to write to Flash.
* @param[in] flash_address Code Flash or Data Flash address to write. The address must be on a
* programming line boundary.
* @param[in] num_bytes The number of bytes to write. This number must be a multiple
* of the programming size. For Code Flash this is FLASH_MIN_PGM_SIZE_CF.
* For Data Flash this is FLASH_MIN_PGM_SIZE_DF.
* @warning Specifying a number that is not a multiple of the programming size
* will result in SF_FLASH_ERR_BYTES being returned and no data written.
*/
ssp_err_t (* write)(flash_ctrl_t * const p_ctrl,
uint32_t const src_address,
uint32_t const flash_address,
uint32_t const num_bytes);
/** Read FLASH device.
* @par Implemented as
* - R_FLASH_LP_Read()
* - R_FLASH_HP_Read()
*
* @param[in] p_ctrl Control for the FLASH device context.
* @param[in] p_dest_address Pointer to caller's destination buffer used to hold the data read from Flash.
* @param[in] flash_address Code Flash or Data Flash starting address to read from.
* @param[in] num_bytes The number of bytes to read.
*/
ssp_err_t (* read)(flash_ctrl_t * const p_ctrl,
uint8_t * const p_dest_address,
uint32_t const flash_address,
uint32_t const num_bytes);
/** Erase FLASH device.
* @par Implemented as
* R_FLASH_LP_Erase()
* R_FLASH_HP_Erase()
*
* @param[in] p_ctrl Control for the FLASH device.
* @param[in] address The block containing this address is the first block erased.
* @param[in] num_blocks Specifies the number of blocks to be erased, the starting block determined
* by the block_erase_address.
*/
ssp_err_t (* erase)(flash_ctrl_t * const p_ctrl,
uint32_t const address,
uint32_t const num_blocks);
/** Blank check FLASH device.
* @par Implemented as
* - R_FLASH_LP_BlankCheck()
* - R_FLASH_HP_BlankCheck()
*
* @param[in] p_ctrl Control for the FLASH device context.
* @param[in] address The starting address of the Flash area to blank check.
* @param[in] num_bytes Specifies the number of bytes that need to be checked.
* See the specific handler for details.
* @param[out] p_blank_check_result Pointer that will be populated by the API with the results of the blank check
* operation in non-BGO (blocking) mode. In this case the blank check operation
* completes here and the result is returned. In Data Flash BGO mode the blank
* check operation is only started here and the result obtained later when the
* supplied callback routine is called. In this case FLASH_RESULT_BGO_ACTIVE will
* be returned in p_blank_check_result.
*/
ssp_err_t (* blankCheck)(flash_ctrl_t * const p_ctrl,
uint32_t const address,
uint32_t const num_bytes,
flash_result_t * const p_blank_check_result);
/** Close FLASH device.
* @par Implemented as
* - R_FLASH_LP_InfoGet()
* - R_FLASH_HP_InfoGet()
*
* @param[in] p_ctrl Pointer to FLASH device control.
* @param[out] p_info Pointer to FLASH info structure.
*/
ssp_err_t (* infoGet)(flash_ctrl_t * const p_ctrl,
flash_info_t * const p_info);
/** Close FLASH device.
* @par Implemented as
* - R_FLASH_LP_Close()
* - R_FLASH_HP_Close()
*
* @param[in] p_ctrl Pointer to FLASH device control.
*/
ssp_err_t (* close)(flash_ctrl_t * const p_ctrl);
/** Get Status for FLASH device.
* @par Implemented as
* - R_FLASH_LP_StatusGet()
* - R_FLASH_HP_StatusGet()
*
* @param[in] p_ctrl Pointer to FLASH device control.
*/
ssp_err_t (* statusGet)(flash_ctrl_t * const p_ctrl);
/** Set Access Window for FLASH device.
* @par Implemented as
* - R_FLASH_LP_AccessWindowSet()
* - R_FLASH_HP_AccessWindowSet()
*
* @param[in] p_ctrl Pointer to FLASH device control.
* @param[in] start_addr Determines the Starting block for the Code Flash access window.
* @param[in] end_addr Determines the Ending block for the Code Flash access window.
*/
ssp_err_t (* accessWindowSet)(flash_ctrl_t * const p_ctrl, uint32_t const start_addr, uint32_t const end_addr);
/** Clear any existing Code Flash access window for FLASH device.
* @par Implemented as
* - R_FLASH_LP_AccessWindowClear()
* - R_FLASH_HP_AccessWindowClear()
*
* @param[in] p_ctrl Pointer to FLASH device control.
* @param[in] start_addr Determines the Starting block for the Code Flash access window.
* @param[in] end_addr Determines the Ending block for the Code Flash access window.
*/
ssp_err_t (* accessWindowClear)(flash_ctrl_t * const p_ctrl);
/** Set ID Code for FLASH device. Setting the ID code can restrict access to the device. The ID code will be
* required to connect to the device. Bits 126 and 127 are set based on the mode.
* e.g. uint8_t id_bytes[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
* 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x00};
* with mode FLASH_ID_CODE_MODE_LOCKED_WITH_ALL_ERASE_SUPPORT
* will result in an ID code of 00112233445566778899aabbccddeec0
* and with mode FLASH_ID_CODE_MODE_LOCKED
* will result in an ID code of 00112233445566778899aabbccddee80
*
* @par Implemented as
* - R_FLASH_LP_IdCodeSet()
* - R_FLASH_HP_IdCodeSet()
*
* @param[in] p_ctrl Pointer to FLASH device control.
* @param[in] p_id_bytes Ponter to the ID Code to be written.
* @param[in] mode Mode used for checking the ID code.
*/
ssp_err_t (* idCodeSet)(flash_ctrl_t * const p_ctrl, uint8_t const * const p_id_bytes, flash_id_code_mode_t mode);
/** Reset function for FLASH device.
* @par Implemented as
* - R_FLASH_LP_Reset()
* - R_FLASH_HP_Reset()
*
* @param[in] p_ctrl Pointer to FLASH device control.
*/
ssp_err_t (* reset)(flash_ctrl_t * const p_ctrl);
/** Update Flash clock frequency (FCLK) and recalculate timeout values
* @par Implemented as
* - R_FLASH_LP_UpdateFlashClockFreq()
* - R_FLASH_HP_UpdateFlashClockFreq()
* @param[in] p_ctrl Pointer to FLASH device control.
*/
ssp_err_t (* updateFlashClockFreq)(flash_ctrl_t * const p_ctrl);
/** Select which block - Default (Block 0) or Alternate (Block 1) is used as the start-up area block.
* @par Implemented as
* - R_FLASH_LP_StartUpAreaSelect()
* - R_FLASH_HP_StartUpAreaSelect()
*
* @param[in] p_ctrl Pointer to FLASH device control.
* @param[in] swap_type FLASH_STARTUP_AREA_BLOCK0, FLASH_STARTUP_AREA_BLOCK1 or FLASH_STARTUP_AREA_BTFLG.
* @param[in] is_temporary True or false. See table below.
*
* swap_type | is_temporary | Operation
* FLASH_STARTUP_AREA_BLOCK0: false On next reset Startup area will be Block 0.\n
* FLASH_STARTUP_AREA_BLOCK0 | false | On next reset Startup area will be Block 0.
* Block 0.\n
* FLASH_STARTUP_AREA_BLOCK1: false On next reset Startup area will be Block 1.\n
* FLASH_STARTUP_AREA_BLOCK1 | true | Startup area is immediately, but temporarily switched to Block 1.
* Block 1.\n
* FLASH_STARTUP_AREA_BTFLG | true | Startup area is immediately, but temporarily switched to...
* taken.\n
* the Block determined by the Configuration BTFLG.\n
*/
ssp_err_t (* startupAreaSelect)(flash_ctrl_t * const p_ctrl,
flash_startup_area_swap_t swap_type,
bool is_temporary);
/** Get Flash driver version.
* @par Implemented as
* - R_FLASH_LP_VersionGet()
* - R_FLASH_HP_VersionGet()
*
* @param[out] p_version Returns version.
*/
ssp_err_t (* versionGet)(ssp_version_t * p_version);
} flash_api_t;
/** This structure encompasses everything that is needed to use an instance of this interface. */
typedef struct st_flash_instance
{
flash_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance
flash_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance
flash_api_t const * p_api; ///< Pointer to the API structure for this instance
} flash_instance_t;
/******************************************************************************************************************//**
* @} (end addtogroup FLASH_API)
*********************************************************************************************************************/
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* DRV_FLASH_API_H */

View File

@ -0,0 +1,97 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : r_flash_lp.h
* Description : HLD Interface for the Low-power FLASH peripheral on SC32 MCUs.
***********************************************************************************************************************/
/***********************************************************************************************************************
Includes
***********************************************************************************************************************/
#ifndef R_FLASH_LP_H
#define R_FLASH_LP_H
#include "bsp_api.h"
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
#include "r_flash_api.h"
#include "r_flash_cfg.h"
/*******************************************************************************************************************//**
* @ingroup HAL_Library
* @defgroup FLASH Low Power Flash
* @brief Driver for the Low power Flash Memory (S3A7 and S124).
*
* This module supports the Flash interface for the Low-power FLASH peripheral.
* @{
**********************************************************************************************************************/
/***********************************************************************************************************************
Macro definitions
***********************************************************************************************************************/
#define FLASH_LP_CODE_VERSION_MAJOR (1U)
#define FLASH_LP_CODE_VERSION_MINOR (13U)
/* If Code Flash programming is enabled, then all API functions must execute out of RAM. */
#if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1)
#if defined(__ICCARM__)
#pragma section=".code_in_ram"
#endif
#define PLACE_IN_RAM_SECTION BSP_PLACE_IN_SECTION_V2(".code_in_ram")
#else
#define PLACE_IN_RAM_SECTION
#endif
/***********************************************************************************************************************
Typedef definitions
***********************************************************************************************************************/
/** Flash instance control block. DO NOT INITIALIZE. */
typedef struct st_flash_lp_instance_ctrl
{
uint32_t opened; ///< To check whether api has been opened or not.
void * p_reg; ///< Base address of flash registers
void (*p_callback)(flash_callback_args_t *p_args);
bsp_cache_state_t cache_state; ///< Used to disable and then restore Flash Cache while API is open.
IRQn_Type irq; ///< Flash ready interrupt number
} flash_lp_instance_ctrl_t;
/**********************************************************************************************************************
Exported global variables
***********************************************************************************************************************/
/** @cond INC_HEADER_DEFS_SEC */
/** Filled in Interface API structure for this Instance. */
extern const flash_api_t g_flash_on_flash_lp;
/** @endcond */
/*******************************************************************************************************************//**
* @} (end defgroup FLASH)
***********************************************************************************************************************/
/* This will generate a build error if this file is included and the target MCU used is NOT one of the following. */
#if !defined(BSP_MCU_GROUP_S3A7) && !defined(BSP_MCU_GROUP_S124) && !defined(BSP_MCU_GROUP_S128) && !defined(BSP_MCU_GROUP_S3A3) \
&& !defined(BSP_MCU_GROUP_S3A6) && !defined(BSP_MCU_GROUP_S1JA) && !defined(BSP_MCU_GROUP_S3A1)
#error "r_flash_lp is not a supported module for this board type."
#endif
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif // R_FLASH_LP_H

View File

@ -0,0 +1,677 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_codeflash.c
* Description : Code Flash Control processing for Low Power Flash
**********************************************************************************************************************/
/******************************************************************************
* Includes <System Includes> , Project Includes
******************************************************************************/
#include "bsp_api.h"
#include "r_flash_lp.h"
#include "../hw_flash_lp_private.h"
#include "r_flash_cfg.h"
#include "hw_flash_common.h"
#include "hw_codeflash.h"
/*******************************************************************************************************************//**
* @addtogroup FLASH
* @{
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @} (end FLASH)
**********************************************************************************************************************/
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static r_codeflash_data_t g_code_flash_info = {0U};
static void HW_FLASH_LP_codeflash_write_fpmcr (flash_lp_instance_ctrl_t * const p_ctrl, uint8_t value) PLACE_IN_RAM_SECTION;
static current_parameters_t * gp_flash_settings = {0U};
static flash_lp_macro_info_t macro_info = {0U};
/*******************************************************************************************************************//**
* @brief Transition to Code Flash P/E mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval none
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_enter_pe_mode (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** While the Flash API is in use we will disable the FLash Cache. */
p_ctrl->cache_state = BSP_CACHE_STATE_OFF;
R_BSP_CacheOff(&p_ctrl->cache_state);
if (SSP_INVALID_VECTOR != p_ctrl->irq)
{
NVIC_DisableIRQ(p_ctrl->irq); ///< We are not supporting Flash Rdy interrupts for Code Flash operations
}
p_faci_reg->FENTRYR = FENTRYR_CODEFLASH_PE_MODE;
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, DISCHARGE_1);
/** Wait for 2us over (tDIS) */
HW_FLASH_LP_delay_us(WAIT_TDIS, gp_flash_settings->system_clock_freq);
if (R_SYSTEM->OPCCR_b.OPCM == 0U) ///< High speed mode?
{
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, DISCHARGE_2);
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, CODEFLASH_PE_MODE);
/** Wait for 5us over (tMS) */
HW_FLASH_LP_delay_us(WAIT_TMS_HIGH, gp_flash_settings->system_clock_freq);
}
else
{
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, DISCHARGE_2 | LVPE_MODE);
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, CODEFLASH_PE_MODE | LVPE_MODE);
/** Wait for 3us over (tMS) */
HW_FLASH_LP_delay_us(WAIT_TMS_MID, gp_flash_settings->system_clock_freq);
}
p_faci_reg->FISR_b.PCKA = (uint32_t)((gp_flash_settings->flash_clock_freq - 1UL) & (uint32_t)0x1F);
}
/*******************************************************************************************************************//**
* @brief This function switches the peripheral from P/E mode for Code Flash to Read mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS Successfully entered read mode.
* @retval SSP_ERR_TIMEOUT Timed out waiting for confirmation of transition to read mode
*
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_codeflash_enter_read_mode (flash_lp_instance_ctrl_t * const p_ctrl)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Timeout counter. */
volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, DISCHARGE_2);
/** Wait for 2us over (tDIS) */
HW_FLASH_LP_delay_us(WAIT_TDIS, gp_flash_settings->system_clock_freq);
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, DISCHARGE_1);
HW_FLASH_LP_codeflash_write_fpmcr(p_ctrl, READ_MODE);
/** Wait for 5us over (tMS) */
HW_FLASH_LP_delay_us(WAIT_TMS_HIGH, gp_flash_settings->system_clock_freq);
/** Clear the P/E mode register */
p_faci_reg->FENTRYR = FENTRYR_READ_MODE;
/** Loop until the Flash P/E mode entry register is cleared or a timeout occurs. If timeout occurs return error. */
while (0x0000U != p_faci_reg->FENTRYR)
{
/* Confirm that the written value can be read correctly. */
if (wait_cnt <= (uint32_t)0)
{
/** Restore the FLash Cache state to what it was before we opened the Flash API. */
R_BSP_CacheSet(p_ctrl->cache_state);
/* return timeout status*/
return SSP_ERR_TIMEOUT;
}
wait_cnt--;
}
/** Restore the FLash Cache state to what it was before we opened the Flash API. */
R_BSP_CacheSet(p_ctrl->cache_state);
return err;
}
/*******************************************************************************************************************//**
* @brief Initiates a Write sequence to the Low Power Code Flash data. Address validation has already been
* performed by the caller.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] src_start_address Start address of the (RAM) area which stores the programming data.
* @param[in] dest_start_address Flash Start address which will be written.
* @param[in] num_bytes Number of bytes to write.
* @param[in] min_program_size Minimum flash programming size.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address, uint32_t dest_start_address, uint32_t num_bytes,
uint32_t min_program_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
g_code_flash_info.start_addr = src_start_address; // Ram Source for data to write
g_code_flash_info.end_addr = dest_start_address; // Flash Start address which will be written
uint32_t temp = min_program_size;
uint32_t right_shift = 0U;
while (1U != temp)
{
temp >>= 1;
right_shift++;
}
/** Calculate the number of writes needed. */
/* This is done with right shift instead of division to avoid using the division library, which would be in flash
* and cause a jump from RAM to flash. */
g_code_flash_info.write_cnt = num_bytes >> right_shift; // Number of units to write
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
/** Initiate the code flash write operation. */
HW_FLASH_LP_codeflash_write_operation(p_ctrl, src_start_address, dest_start_address, min_program_size);
}
/*******************************************************************************************************************//**
* @brief Execute a single Write operation on the Low Power Code Flash data.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] psrc_addr Source address for data to be written.
* @param[in] dest_addr End address (read form) for writing.
* @param[in] min_program_size Minimum flash programming size.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_write_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t psrc_addr, const uint32_t dest_addr,
uint32_t min_program_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint8_t * data8_ptr;
data8_ptr = (uint8_t *)psrc_addr;
uint16_t load_value;
uint8_t byteL;
uint8_t byteH;
/** Write flash address setting */
p_faci_reg->FSARH = (uint16_t) ((dest_addr >> 16) & 0xFFFF);
p_faci_reg->FSARL = (uint16_t) (dest_addr & 0xFFFF);
/** Write data address setting. */
/* Note that the caller could be providing a data buffer that was defined as a char[] buffer. As
* a result it might not be 16 bit aligned. For the CM0 data accesses that are not aligned will generate
* a fault. Therefore we will read the data 8 bits at a time.*/
byteL = *data8_ptr;
data8_ptr++;
byteH = *data8_ptr;
load_value = (uint16_t)(((uint16_t)byteH << 8) | (uint16_t)byteL);
data8_ptr++;
p_faci_reg->FWBL0 = load_value; // Move to bits 31 - 0 for next write.
byteL = *data8_ptr;
data8_ptr++;
byteH = *data8_ptr;
load_value = (uint16_t)(((uint16_t)byteH << 8) | (uint16_t)byteL);
data8_ptr++;
p_faci_reg->FWBH0 = load_value;
if (min_program_size > 4U)
{
byteL = *data8_ptr;
data8_ptr++;
byteH = *data8_ptr;
load_value = (uint16_t)(((uint16_t)byteH << 8) | (uint16_t)byteL);
data8_ptr++;
p_faci_reg->FWBL1 = load_value;
byteL = *data8_ptr;
data8_ptr++;
byteH = *data8_ptr;
load_value = (uint16_t)(((uint16_t)byteH << 8) | (uint16_t)byteL);
data8_ptr++;
p_faci_reg->FWBH1 = load_value;
}
/** Execute Write command */
p_faci_reg->FCR = FCR_WRITE;
}
/*******************************************************************************************************************//**
* @brief Waits for the write command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] min_program_size Minimum flash programming size.
* @retval SSP_SUCCESS Write command successfully completed.
* @retval SSP_ERR_IN_USE Write command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for write command completion.
* @retval SSP_ERR_WRITE_FAILED Write failed. Flash could be locked, area has not been erased or
* address could be under access window control.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_codeflash_write_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t min_program_size)
{
ssp_err_t status;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/* Worst case timeout */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_write_cf;
/** Check the Flash Ready Flag bit*/
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/* if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
return SSP_ERR_IN_USE;
}
/** Clear FCR register */
p_faci_reg->FCR = FCR_CLEAR;
/* Worst case timeout */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_write_cf;
/** Wait for the Flash Ready Flag bit to indicate ready or a timeout to occur. If timeout return error. */
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/** Check that execute command is completed. */
/** Wait until FRDY is 1 unless timeout occurs. */
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/** if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If invalid command status or programming failed status return error*/
if ((0U != p_faci_reg->FSTATR2_b.ILGLERR) || (0U != p_faci_reg->FSTATR2_b.PRGERR1))
{
HW_FLASH_LP_reset(p_ctrl);
status = SSP_ERR_WRITE_FAILED;
}
else
{
/** If there is more data to write then write the next data. */
g_code_flash_info.start_addr += min_program_size;
g_code_flash_info.end_addr += min_program_size;
g_code_flash_info.write_cnt--;
if (g_code_flash_info.write_cnt)
{
HW_FLASH_LP_codeflash_write_operation(p_ctrl, g_code_flash_info.start_addr, g_code_flash_info.end_addr,
min_program_size);
status = SSP_ERR_IN_USE;
}
else
{
status = SSP_SUCCESS;
}
}
/** Return status. */
return status;
}
/*******************************************************************************************************************//**
* @brief Initiates the Erase sequence to Erase the number of Code Flash blocks specified by num_blocks, starting with the
* Block containing 'address'.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr - The block containing this address is the first block to be erased.
* @param[in] num_blocks - The # of blocks to be erased.
* @param[in] block_size - Size of this Flash block.
* @retval None.
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_erase (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, const uint32_t num_blocks, uint32_t block_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Configure the start and end addresses. */
g_code_flash_info.start_addr = start_addr;
g_code_flash_info.end_addr = (start_addr + ((num_blocks * block_size) - 1U));
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
/** Start the code flash erase operation. */
HW_FLASH_LP_codeflash_erase_operation(p_ctrl, start_addr, block_size);
}
/*******************************************************************************************************************//**
* @brief Execute a single Erase operation on the Low Power Code Flash data.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Starting Code Flash address to erase.
* @param[in] block_size - Size of this Flash block.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_erase_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t block_size)
{
uint32_t block_start_addr;
uint32_t block_end_addr;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
block_start_addr = start_addr;
block_end_addr = (block_start_addr + (block_size - 1U));
/* Erase start address setting */
p_faci_reg->FSARH = (uint16_t) ((block_start_addr >> 16) & 0xFFFFU);
p_faci_reg->FSARL = (uint16_t) (block_start_addr & 0xFFFFU);
/* Erase end address setting */
p_faci_reg->FEARH = ((block_end_addr >> 16) & 0xFFFFU);
p_faci_reg->FEARL = (uint16_t) (block_end_addr & 0xFFFFU);
/* Execute Erase command */
p_faci_reg->FCR = FCR_ERASE;
}
/*******************************************************************************************************************//**
* @brief Waits for the erase command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] block_size - Size of this Flash block.
* @retval SSP_SUCCESS Erase command successfully completed.
* @retval SSP_ERR_IN_USE Erase command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for erase command completion.
* @retval SSP_ERR_WRITE_FAILED Erase failed. Flash could be locked or address could be under access window
* control.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_codeflash_erase_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_size)
{
ssp_err_t status;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If the flash operation has not completed return error. */
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear the Flash Control Register */
p_faci_reg->FCR = FCR_CLEAR;
/** Prepare worst case timeout */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_erase_cf_block;
/** Wait until the ready flag is set or timeout. If timeout return error */
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/** Check that execute command is completed. */
/** Wait until FRDY is 1 unless timeout occurs. */
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/* if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If invalid command or erase error flag is set reset and return error. */
if ((0U != p_faci_reg->FSTATR2_b.ILGLERR) || (0U != p_faci_reg->FSTATR2_b.ERERR))
{
HW_FLASH_LP_reset(p_ctrl);
return SSP_ERR_WRITE_FAILED;
}
else
{
/** If there are more blocks to erase initiate another erase operation. Otherwise return success. */
g_code_flash_info.start_addr += block_size;
/* Check for CF0 overflow. */
if ((g_code_flash_info.start_addr < g_code_flash_info.end_addr) && (g_code_flash_info.start_addr != 0U))
{
HW_FLASH_LP_codeflash_erase_operation(p_ctrl, g_code_flash_info.start_addr, block_size);
status = SSP_ERR_IN_USE;
}
else
{
status = SSP_SUCCESS;
}
}
return status;
}
/*******************************************************************************************************************//**
* @brief Initiates a Blank check sequence to the Low Power Code Flash data. Address validation has already been
* performed by the caller.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Start address of the Code Flash area to blank check.
* @param[in] num_bytes Number of bytes to blank check beginning at start_addr.
*
* @retval SSP_SUCCESS Blank check command successfully issued to FACI controller.
* @retval SSP_ERR_INVALID_ADDRESS The address and num_bytes supplied do not exist in any of the Code Flash macros.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_codeflash_blank_check (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t num_bytes)
{
ssp_err_t status = SSP_SUCCESS;
gp_flash_settings->total_count = num_bytes; /* Total Number of bytes to blank check */
gp_flash_settings->dest_addr = start_addr;
/** Get the macro information for this address. If failure skip blank check and return error. */
status = HW_FLASH_LP_code_get_macro_info(start_addr, num_bytes, &macro_info);
gp_flash_settings->current_count = macro_info.allowed_bytes;
/** If successful initiate the code flash blank check operation. */
if (status == SSP_SUCCESS)
{
HW_FLASH_LP_codeflash_blank_check_operation(p_ctrl, start_addr, macro_info.allowed_bytes);
}
/** Return status */
return(status);
}
/*******************************************************************************************************************//**
* @brief Initiates a Blank check sequence to the Low Power Code Flash data. Address validation has already been
* performed by the caller.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Start address of the Code Flash area to blank check.
* @param[in] num_bytes Number of bytes to blank check beginning at start_addr.
*
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_codeflash_blank_check_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t num_bytes)
{
uint32_t start_addr_idx;
uint32_t end_addr_idx;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
start_addr_idx = start_addr;
end_addr_idx = start_addr_idx + (num_bytes - 1U);
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
/** BlankCheck start address setting */
p_faci_reg->FSARH = (uint16_t) ((start_addr_idx >> 16) & 0xFFFFU);
p_faci_reg->FSARL = (uint16_t) (start_addr_idx & 0xFFFFU);
/** BlankCheck end address setting */
p_faci_reg->FEARH = ((end_addr_idx >> 16) & 0xFFFFU);
p_faci_reg->FEARL = (uint16_t) (end_addr_idx & 0xFFFFU);
/** Execute BlankCheck command */
p_faci_reg->FCR = FCR_BLANKCHECK;
}
/*******************************************************************************************************************//**
* @brief Waits for the blank check command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS Blank check command successfully completed.
* @retval SSP_ERR_IN_USE Blank check command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for Blank check command completion.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_codeflash_blank_check_monitor (flash_lp_instance_ctrl_t * const p_ctrl)
{
ssp_err_t status = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
gp_flash_settings->bc_result = FLASH_RESULT_BLANK;
/** If the flash has not completed the software command return error. */
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear the Flash Control Register */
p_faci_reg->FCR = FCR_CLEAR;
/** Prepare worst case timeout counter */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_blank_check;
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/** Check that execute command is completed. */
/** Wait until FRDY is 1 unless timeout occurs. If timeout return error. */
if (gp_flash_settings->wait_cnt <= 0U)
{
/** if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If illegal command, reset and return error. */
if (0U != p_faci_reg->FSTATR2_b.ILGLERR)
{
HW_FLASH_LP_reset(p_ctrl);
status = SSP_ERR_WRITE_FAILED;
}
else
{
if (0U != p_faci_reg->FSTATR00_b.BCERR0) // Tested Flash Area is not blank
{
/** If the result is already NOT Blank there is no reason to continue with any subsequent checks, simply return */
gp_flash_settings->bc_result = FLASH_RESULT_NOT_BLANK;
status = SSP_SUCCESS;
}
else
{
/* Only S3A7 (2 CF macros) Code Flash blank checking is concerned with hardware macros and spanning boundaries. */
/** If the flash has more than one code flash macro */
if (gp_flash_settings->flash_cf_macros > 1U)
{
/** If there is more data to blank check adjust the operation settings. */
gp_flash_settings->total_count -= gp_flash_settings->current_count; /* Update remaining amount to BC. */
gp_flash_settings->dest_addr += gp_flash_settings->current_count;
/** Get the macro information for this address */
status = HW_FLASH_LP_code_get_macro_info(gp_flash_settings->dest_addr, gp_flash_settings->total_count, &macro_info);
gp_flash_settings->current_count = macro_info.allowed_bytes;
/** If the original request was split as it spanms flash hardware macros */
if (gp_flash_settings->total_count != 0U)
{
/** Begin next Blankcheck operation. */
HW_FLASH_LP_codeflash_blank_check_operation(p_ctrl, gp_flash_settings->dest_addr, macro_info.allowed_bytes);
status = SSP_ERR_IN_USE;
}
else
{
status = SSP_SUCCESS;
}
}
}
}
/** Return status. */
return status;
}
/*******************************************************************************************************************//**
* @brief Sets the FPMCR register, used to place the Flash sequencer in Code Flash P/E mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] value - 8 bit value to be written to the FPMCR register.
* @retval none.
**********************************************************************************************************************/
static void HW_FLASH_LP_codeflash_write_fpmcr (flash_lp_instance_ctrl_t * const p_ctrl, uint8_t value)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
p_faci_reg->FPR = 0xA5U;
p_faci_reg->FPMCR = value;
p_faci_reg->FPMCR = (uint8_t) ~value;
p_faci_reg->FPMCR = value;
if (value == p_faci_reg->FPMCR)
{
__NOP();
}
}
/*******************************************************************************
* Outline : Give the Code Flash HW layer access to the flash settings
* Header : none
* Function Name: set_flash_settings
* Description : Give the HW layer access to the flash settings
* @param[in] p_current_parameters - Pointer the settings.
* :
* Return Value : none
*******************************************************************************/
void HW_FLASH_LP_code_flash_set_flash_settings (current_parameters_t * const p_current_parameters)
{
gp_flash_settings = p_current_parameters;
}
/*******************************************************************************************************************//**
* @brief Given an address and number of bytes, determine how many of those bytes are in a single Flash macro.
* @param[in] address Address to query
* @param[in] num_bytes Number of byte starting at Address
* @param[in] p_macro Pointer to the Flash macro information
* @retval SSP_ERR_INVALID_ADDRESS The address and num_bytes supplied do not exist in any of the Code or Data Flash macros.
* @retval SSP_SUCCESS Successful query. p_macro contains details.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_code_get_macro_info (uint32_t const address, uint32_t num_bytes, flash_lp_macro_info_t * const p_macro)
{
ssp_err_t err;
p_macro->allowed_bytes = num_bytes;
p_macro->macro_st_addr = address;
/* Only S3A7 (2 CF macros) Code Flash blank checking is concerned with hardware macros and spanning boundaries. */
/** If the MCU has more than one code flash macro determine the macro the requested address is in. */
if (gp_flash_settings->flash_cf_macros > 1U)
{
err = SSP_ERR_INVALID_ADDRESS;
p_macro->macro_size = gp_flash_settings->cf_macro_size; // The size of the implemented Code Flash macro
p_macro->total_macros = gp_flash_settings->flash_cf_macros;
p_macro->macro_st_addr = gp_flash_settings->cf_memory_st_addr;
p_macro->macro_end_addr = (p_macro->macro_st_addr + p_macro->macro_size) - 1U;
for (uint32_t i=0U; i<p_macro->total_macros; i++)
{
/* Is the address in the range of this macro? */
if ((address >= p_macro->macro_st_addr) && (address <= p_macro->macro_end_addr))
{
/* Yes, how many bytes can be accommodated out of the request? */
if (((p_macro->macro_end_addr - address) + 1U) < num_bytes)
{
p_macro->allowed_bytes = (p_macro->macro_end_addr - address) + 1U;
}
err = SSP_SUCCESS;
break;
}
else
{
p_macro->macro_st_addr = p_macro->macro_end_addr + 1U;
p_macro->macro_end_addr = (p_macro->macro_st_addr + p_macro->macro_size) - 1U;
}
}
}
else
{
err = SSP_SUCCESS;
}
return err;
}

View File

@ -0,0 +1,110 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_codeflash.h
* Description : Code Flash Control processing for Low Power Flash
**********************************************************************************************************************/
#ifndef R_CODEFLASH_H
#define R_CODEFLASH_H
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/******************************************************************************
* Macro definitions
******************************************************************************/
/* flash mode definition (FENTRYR Register setting)*/
#define FENTRYR_CODEFLASH_PE_MODE (0xAA01U)
#define FENTRYR_READ_MODE (0xAA00U)
/* flash mode definition (FPMCR Register setting)*/
#define DISCHARGE_1 (0x12U)
#define DISCHARGE_2 (0x92U)
#define CODEFLASH_PE_MODE (0x82U)
#define READ_MODE (0x08U)
#define LVPE_MODE (0x40U)
/* operation definition (FCR Register setting)*/
#define FCR_WRITE (0x81U)
#define FCR_ERASE (0x84U)
#define FCR_BLANKCHECK (0x83U)
#define FCR_CLEAR (0x00U)
#define OPCCR_HIGH_SPEED_MODE (0x00U)
/******************************************************************************
* Typedef definitions
******************************************************************************/
typedef struct R_CODEFLASH_DATA_T
{
uint32_t start_addr; /* start address (Erase) or Ram Source for Write, Dest for read */
uint32_t end_addr; /* end address (Erase), or Flash Start address which will be read/written */
uint32_t write_cnt; /* units remaining to do */
} r_codeflash_data_t;
/******************************************************************************
* Exported global variables
******************************************************************************/
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void HW_FLASH_LP_codeflash_enter_pe_mode (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_codeflash_enter_read_mode (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_codeflash_erase (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr,
const uint32_t num_blocks,
uint32_t block_size) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_codeflash_erase_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr,
uint32_t block_size) PLACE_IN_RAM_SECTION;
ssp_err_t HW_FLASH_LP_codeflash_erase_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_size) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_codeflash_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address,
uint32_t dest_start_address,
uint32_t num_bytes,
uint32_t min_program_size) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_codeflash_write_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t psrc_addr,
const uint32_t dest_addr,
uint32_t min_program_size) PLACE_IN_RAM_SECTION;
ssp_err_t HW_FLASH_LP_codeflash_write_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t min_program_size) PLACE_IN_RAM_SECTION;
ssp_err_t HW_FLASH_LP_codeflash_blank_check (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t num_bytes) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_codeflash_blank_check_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t num_bytes) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_codeflash_blank_check_monitor (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void HW_FLASH_LP_code_flash_set_flash_settings (current_parameters_t * const p_current_parameters) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_code_get_macro_info (uint32_t const address, uint32_t num_bytes, flash_lp_macro_info_t * const p_macro) PLACE_IN_RAM_SECTION;
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* R_CODEFLASH_H */

View File

@ -0,0 +1,389 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_codeflash_extra.c
* Description : Flash Control Access window and swap control processing for Low Power Flash
**********************************************************************************************************************/
/******************************************************************************
* Includes <System Includes> , Project Includes
******************************************************************************/
#include "bsp_api.h"
#include "r_flash_lp.h"
#include "../hw_flash_lp_private.h"
#include "r_flash_cfg.h"
#include "hw_flash_common.h"
#include "hw_dataflash.h"
#include "hw_codeflash.h"
#include "hw_codeflash_extra.h"
/*******************************************************************************************************************//**
* @addtogroup FLASH
* @{
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @} (end FLASH)
**********************************************************************************************************************/
/******************************************************************************
* Private global variables and functions
******************************************************************************/
/*******************************************************************************************************************//**
* @brief Temporarily sets the startup area to use the DEFAULT or ALTERNATE area as requested.
* On the next subsequent reset, the startup area will be determined by the state of the BTFLG.
* This command does NOT modify the configuration via The Configuration Set command, hence these changes are
* only in effect until the next reset.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] swap_type - specifies the startup area swap being requested.
*
* @retval SSP_SUCCESS StartUp area temporarily modified.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_set_startup_area_temporary (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Set the Flash initial setting startup area select bit as requested. */
if (FLASH_STARTUP_AREA_BLOCK0 == swap_type)
{
p_faci_reg->FISR_b.SAS = SAS_DEFAULT_AREA;
}
else if (FLASH_STARTUP_AREA_BLOCK1 == swap_type)
{
p_faci_reg->FISR_b.SAS = SAS_ALTERNATE_AREA;
}
else
{
p_faci_reg->FISR_b.SAS = (uint32_t)SAS_PER_BTFLG_AREA;
}
return err;
}
/*******************************************************************************************************************//**
* @brief Configure an access window for the Code Flash memory using the provided start and end address. An access
* window defines a contiguous area in Code Flash for which programming/erase is enabled. This area is
* on block boundaries.
* The block containing start_addr is the first block. The block containing end_addr is the last block.
* The access window then becomes first block - last block inclusive. Anything outside this range
* of Code Flash is then write protected.
* This command DOES modify the configuration via The Configuration Set command to update the FAWS and FAWE.
*
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Determines the Starting block for the Code Flash access window.
* @param[in] end_addr Determines the Ending block for the Code Flash access window.
*
* @retval SSP_SUCCESS Access window successfully configured.
* @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
* @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
* command.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_access_window_set (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const start_addr, uint32_t const end_addr)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t start_addr_idx;
uint32_t end_addr_idx;
start_addr_idx = start_addr;
end_addr_idx = end_addr;
/** Select The Extra Area */
p_faci_reg->FASR_b.EXS = 1U;
/** Set the access window. */
HW_FLASH_LP_extra_operation(p_ctrl, start_addr_idx, end_addr_idx, FLASH_COMMAND_ACCESSWINDOW);
/** Wait for the operation to complete or error. */
do
{
err = HW_FLASH_LP_extra_check(p_ctrl);
} while (SSP_ERR_IN_USE == err);
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
/** Return status. */
return err;
}
/*******************************************************************************************************************//**
* @brief Remove any access window that is currently configured in the Code Flash.
* This command DOES modify the configuration via The Configuration Set command to update the FAWS and FAWE.
* Subsequent to this call all Code Flash is writable.
*
* @retval SSP_SUCCESS Access window successfully removed.
* @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
* @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
* command.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
* @param[in] p_ctrl Pointer to the Flash control block
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_access_window_clear (flash_lp_instance_ctrl_t * const p_ctrl)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Select Extra Area */
p_faci_reg->FASR_b.EXS = 1U;
// Setting the accesswindow to 0,0 will clear any configured access window.
/** Call extra operation to clear the access window. */
HW_FLASH_LP_extra_operation(p_ctrl, 0, 0, FLASH_COMMAND_ACCESSWINDOW);
/** Wait until the operation is complete or an error. */
do
{
err = HW_FLASH_LP_extra_check(p_ctrl);
} while (SSP_ERR_IN_USE == err);
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
return err;
}
/*******************************************************************************************************************//**
* @brief Set the id code
*
* @param p_ctrl The p control
* @param p_id_code Pointer to the code to be written
* @param[in] mode The id code mode
*
* @retval SSP_SUCCESS The id code have been written.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for completion of extra command.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_set_id_code (flash_lp_instance_ctrl_t * const p_ctrl,
uint8_t const * const p_id_code,
flash_id_code_mode_t mode)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t fexcr_command = FEXCR_OCDID1;
uint16_t mode_mask = 0U;
if(FLASH_ID_CODE_MODE_LOCKED_WITH_ALL_ERASE_SUPPORT == mode)
{
mode_mask = 0xC000U;
}
if(FLASH_ID_CODE_MODE_LOCKED == mode)
{
mode_mask = 0x8000U;
}
/* Timeout counter. */
volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
/** For each ID byte register */
for(uint32_t i = 0U; i < 16U; i+=4U)
{
/** Select Extra Area */
p_faci_reg->FASR_b.EXS = 1U;
/** Write the ID Bytes. If mode is unlocked write all 0xFF. Write the mode mask to the MSB. */
if(FLASH_ID_CODE_MODE_UNLOCKED == mode)
{
p_faci_reg->FWBL0 = 0xFFFFU;
p_faci_reg->FWBH0 = 0xFFFFU;
}
else
{
/* The id code array may be unaligned. Do not attempt to optimize this code to prevent unaligned access. */
p_faci_reg->FWBL0 = (uint32_t)(p_id_code[i] | ((uint32_t)p_id_code[i+1] << 8));
if(12U == i)
{
p_faci_reg->FWBH0 = (uint32_t)(p_id_code[i+2] | ((uint32_t)p_id_code[i+3] << 8)) | mode_mask;
}
else
{
p_faci_reg->FWBH0 = (uint32_t)(p_id_code[i+2] | ((uint32_t)p_id_code[i+3] << 8));
}
}
/** Execute OCDID command */
p_faci_reg->FEXCR = fexcr_command;
/** Increment the command to write to the next OCDID bytes */
fexcr_command++;
/** Wait until the operation is complete or an error. */
do
{
err = HW_FLASH_LP_extra_check(p_ctrl);
wait_cnt--;
if(wait_cnt == 0U)
{
err = SSP_ERR_TIMEOUT;
}
} while (SSP_ERR_IN_USE == err);
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
/** If failure return error */
if(SSP_SUCCESS != err)
{
return err;
}
}
return err;
}
/*******************************************************************************************************************//**
* @brief Modifies the start-up program swap flag (BTFLG) based on the supplied parameters. These changes will
* take effect on the next reset. This command DOES modify the configuration via The Configuration
* Set command to update the BTFLG.
*
* @retval SSP_SUCCESS Access window successfully removed.
* @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
* @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
* command.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
*
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] swap_type - specifies the startup area swap being requested.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_set_startup_area_boot (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t startup_area_mask = (uint32_t)((uint32_t)swap_type << 8); // move selection to bit 8
/** Select Extra Area */
p_faci_reg->FASR_b.EXS = 1U;
/** Call extra operation to set the startup area. */
HW_FLASH_LP_extra_operation(p_ctrl, startup_area_mask, 0, FLASH_COMMAND_STARTUPAREA);
/** Wait until the operation is complete or an error occurs. */
do
{
err = HW_FLASH_LP_extra_check(p_ctrl);
} while (SSP_ERR_IN_USE == err);
/** Select User Area */
p_faci_reg->FASR_b.EXS = 0U;
return err;
}
/*******************************************************************************************************************//**
* @brief Command processing for the extra area.
*
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr_startup_value Determines the Starting block for the Code Flash access window.
* @param[in] end_addr Determines the Ending block for the Code Flash access window.
* @param[in] command Select from R_FLASH_ACCESSWINDOW or R_FLASH_STARTUPAREA.
*
**********************************************************************************************************************/
void HW_FLASH_LP_extra_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr_startup_value,
const uint32_t end_addr,
r_flash_command_t command)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/* Per the spec: */
/* Setting data to the FWBL0 register, this command is allowed to select the start-up area from the */
/* default area (blocks 0-3) to the alternative area (blocks 4-7) and set the security. */
/* Bit 8 of the FWBL0 register is 0: the alternative area (blocks 4-7) are selected as the start-up area. */
/* Bit 8 of the FWBL0 register is 1: the default area (blocks 0-3) are selected as the start-up area. */
/* Bit 14 of the FWBL0 register MUST be 1! Setting this bit to zero will clear the FSPR register and lock the */
/* FLASH!!! It is not be possible to unlock it. */
if (FLASH_COMMAND_ACCESSWINDOW == command)
{
/** Set the Access Window start and end addresses. */
/* FWBL0 reg sets the Start Block address. FWBH0 reg sets the end address. */
/* Convert the addresses to their respective block numbers */
p_faci_reg->FWBL0 = ((start_addr_startup_value >> 10) & 0xFFFFU);
p_faci_reg->FWBH0 = ((end_addr >> 10) & 0xFFFFU);
/** Execute Access Window command */
p_faci_reg->FEXCR = FEXCR_AW;
}
else
{
/* Startup Area Flag value setting */
p_faci_reg->FWBH0 = 0xFFFFU;
/* FSPR must be set. Unused bits write value should be 1. */
p_faci_reg->FWBL0 = (start_addr_startup_value | 0xFEFFU);
/** Execute Startup Area Flag command */
p_faci_reg->FEXCR = FEXCR_STARTUP;
}
}
/*******************************************************************************************************************//**
* @brief Verifying the execution result for the extra area.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS The extra command has successfully completed.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for completion of extra command.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_extra_check (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/* Timeout counter. */
volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
/** If the software command of the FEXCR register is not terminated return in use. */
if (1U != p_faci_reg->FSTATR1_b.EXRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear the Flash Extra Area Control Register. */
p_faci_reg->FEXCR = FEXCR_CLEAR;
/** Wait until the command has completed or a timeout occurs. If timeout return error. */
while (0U != p_faci_reg->FSTATR1_b.EXRDY)
{
/* Check that execute command is completed. */
/* Confirm that the written value can be read correctly. */
if (wait_cnt <= (uint32_t)0)
{
/* return timeout status*/
return SSP_ERR_TIMEOUT;
}
wait_cnt--;
}
/** If Extra Area Illegal Command Error Flag or Error during programming reset the flash and return error. */
if ((0U != p_faci_reg->FSTATR00_b.EILGLERR) || (0U != p_faci_reg->FSTATR00_b.PRGERR01))
{
HW_FLASH_LP_reset(p_ctrl);
return SSP_ERR_WRITE_FAILED;
}
/** Return success. */
return SSP_SUCCESS;
}

View File

@ -0,0 +1,92 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_codeflash_extra.h
* Description : Flash Control Access window and swap control processing for Low Power Flash.
**********************************************************************************************************************/
#ifndef R_CODEFLASH_EXTRA_H
#define R_CODEFLASH_EXTRA_H
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/******************************************************************************
* Macro definitions
******************************************************************************/
/* operation definition (FEXCR Register setting)*/
#define FEXCR_STARTUP (0x81U)
#define FEXCR_AW (0x82U)
#define FEXCR_OCDID1 (0x83U)
#define FEXCR_OCDID2 (0x84U)
#define FEXCR_OCDID3 (0x85U)
#define FEXCR_OCDID4 (0x86U)
#define FEXCR_CLEAR (0x00U)
#define DUMMY (0xFFFFFFFFU)
#define DEFAULT_AREA (1U)
#define DEFAULT_AREA_VALUE (0xFFFFU)
#define STARTUP_AREA_VALUE (0xFEFFU)
#define SAS_DEFAULT_AREA 0x02U ///< Bit value for FSUAC register specifying DEFAULT area
#define SAS_ALTERNATE_AREA 0x03U ///< Bit value for FSUAC register specifying ALTERNATE area
#define SAS_PER_BTFLG_AREA 0x00U ///< Bit value for FSUAC register specifying use BTFLG area
/******************************************************************************
* Exported global functions (to be accessed by other files)
******************************************************************************/
/** FLASH operation command values */
typedef enum e_flash_command
{
FLASH_COMMAND_ACCESSWINDOW, /**< Flash access window command */
FLASH_COMMAND_STARTUPAREA /**< Flash change startup area command */
} r_flash_command_t;
ssp_err_t HW_FLASH_LP_access_window_set (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const start_addr, uint32_t const end_addr) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_access_window_clear (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_set_startup_area_temporary (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_set_startup_area_boot (flash_lp_instance_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_set_id_code (flash_lp_instance_ctrl_t * const p_ctrl,
uint8_t const * const p_id_code,
flash_id_code_mode_t mode) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void HW_FLASH_LP_extra_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr_startup_value,
const uint32_t end_addr,
r_flash_command_t command) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_extra_check (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t HW_FLASH_LP_set_startup_area (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t value) PLACE_IN_RAM_SECTION;
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* R_CODEFLASH_EXTRA_H */

View File

@ -0,0 +1,514 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_dataflash.c
* Description : Data Flash Control processing for Low Power Flash
**********************************************************************************************************************/
/******************************************************************************
* Includes <System Includes> , Project Includes
******************************************************************************/
#include "bsp_api.h"
#include "r_flash_lp.h"
#include "../hw_flash_lp_private.h"
#include "r_flash_cfg.h"
#include "hw_flash_common.h"
#include "hw_dataflash.h"
/*******************************************************************************************************************//**
* @addtogroup FLASH
* @{
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @} (end FLASH)
**********************************************************************************************************************/
/******************************************************************************
* Macro definitions
******************************************************************************/
/******************************************************************************
* Private global variables and functions
******************************************************************************/
static current_parameters_t * gp_flash_settings = NULL;
static void HW_FLASH_LP_write_fpmcr (flash_lp_instance_ctrl_t * const p_ctrl, uint8_t value);
/*******************************************************************************************************************//**
* @brief Enable Data Flash Access and wait for the Data Flash STOP recovery time.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval none
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_enable (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Data Flash Access enable */
p_faci_reg->DFLCTL = 1U;
if (1U == p_faci_reg->DFLCTL)
{
__NOP();
}
/** Wait for 5us over (tDSTOP) */
HW_FLASH_LP_delay_us(WAIT_TDSTOP, gp_flash_settings->system_clock_freq);
}
/*******************************************************************************************************************//**
* @brief Transition to Data Flash P/E mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval none
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_enter_pe_mode (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
p_faci_reg->FENTRYR = FENTRYR_DATAFLASH_PE_MODE;
/** If BGO mode is enabled for dataflash and the vector is valid enable the vector. */
if (gp_flash_settings->bgo_enabled_df == true)
{
if (SSP_INVALID_VECTOR != p_ctrl->irq)
{
NVIC_EnableIRQ(p_ctrl->irq); // We are supporting Flash Rdy interrupts for Data Flash operations
}
}
HW_FLASH_LP_delay_us(WAIT_TDSTOP, gp_flash_settings->system_clock_freq);
if (R_SYSTEM->OPCCR_b.OPCM == 0U) ///< High speed mode?
{
HW_FLASH_LP_write_fpmcr(p_ctrl, DATAFLASH_PE_MODE);
}
else
{
HW_FLASH_LP_write_fpmcr(p_ctrl, (uint8_t)DATAFLASH_PE_MODE | (uint8_t)LVPE_MODE);
}
p_faci_reg->FISR_b.PCKA = (gp_flash_settings->flash_clock_freq - 1U) & (uint32_t)0x1F;
}
/*******************************************************************************************************************//**
* @brief This function switches the peripheral from P/E mode for Data Flash to Read mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS Successfully entered read mode.
* @retval SSP_ERR_TIMEOUT Timed out waiting for confirmation of transition to read mode
*
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_dataflash_enter_read_mode (flash_lp_instance_ctrl_t * const p_ctrl)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/* Timeout counter. */
volatile uint32_t wait_cnt = FLASH_FRDY_CMD_TIMEOUT;
/** Set the Flash P/E Mode Control Register to Read mode. */
HW_FLASH_LP_write_fpmcr(p_ctrl, READ_MODE);
/** Wait for 5us over (tMS) */
HW_FLASH_LP_delay_us(WAIT_TMS_HIGH, gp_flash_settings->system_clock_freq);
/** Clear the flash P/E mode entry register */
p_faci_reg->FENTRYR = FENTRYR_READ_MODE;
/** Loop until the Flash P/E mode entry register is cleared or a timeout occurs. If timeout occurs return error. */
while (0x0000U != p_faci_reg->FENTRYR)
{
/* Confirm that the written value can be read correctly. */
if (wait_cnt <= (uint32_t)0)
{
/* return timeout status*/
return SSP_ERR_TIMEOUT;
}
wait_cnt--;
}
return err;
}
/*******************************************************************************************************************//**
* @brief Initiates a Write sequence to the Low Power Data Flash data. Address validation has already been
* performed by the caller.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] src_start_address Start address of the (RAM) area which stores the programming data.
* @param[in] dest_start_address Flash Start address which will be written.
* @param[in] num_bytes Number of bytes to write.
* @param[in] min_program_size The minimum Flash programming size.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address,
uint32_t dest_start_address,
uint32_t num_bytes,
uint32_t min_program_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t temp = min_program_size;
uint32_t right_shift = 0U;
while (1U != temp)
{
temp >>= 1;
right_shift++;
}
/** Calculate the number of writes. Each write is of length min_program_size. */
/** Configure the flash settings. */
/* This is done with right shift instead of division to avoid using the division library, which would be in flash
* and cause a jump from RAM to flash. */
gp_flash_settings->total_count = num_bytes >> right_shift; /* Number of bytes to write */
gp_flash_settings->dest_addr = dest_start_address;
gp_flash_settings->src_addr = src_start_address;
gp_flash_settings->current_count = (uint32_t)0;
p_faci_reg->FASR_b.EXS = 0U;
/** Initiate the data flash write operation. */
HW_FLASH_LP_dataflash_write_operation(p_ctrl, src_start_address, dest_start_address);
}
/*******************************************************************************************************************//**
* @brief Execute a single Write operation on the Low Power Data Flash data.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] psrc_addr Source address for data to be written.
* @param[in] dest_addr End address (read form) for writing.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_write_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t psrc_addr, uint32_t dest_addr)
{
uint32_t dest_addr_idx;
uint8_t * data8_ptr;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
data8_ptr = (uint8_t *)psrc_addr;
dest_addr_idx = dest_addr + DATAFLASH_ADDR_OFFSET; /* Conversion to the P/E address from the read address */
/** Write flash address setting */
p_faci_reg->FSARH = (uint16_t) ((uint32_t)(dest_addr_idx >> 16) & 0xFFFF);
p_faci_reg->FSARL = (uint16_t) (dest_addr_idx & 0xFFFF);
/** Write data address setting */
p_faci_reg->FWBL0 = *data8_ptr; // For data flash there are only 8 bits used of the 16 in the reg
/** Execute Write command */
p_faci_reg->FCR = FCR_WRITE;
}
/*******************************************************************************************************************//**
* @brief Waits for the write command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] min_program_size The minimum Flash programming size.
* @retval SSP_SUCCESS Write command successfully completed.
* @retval SSP_ERR_IN_USE Write command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for write command completion.
* @retval SSP_ERR_WRITE_FAILED Write failed. Flash could be locked, area has not been erased, or address
* could be under access window control.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_dataflash_write_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t min_program_size)
{
ssp_err_t status;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If the flash has not completed the software command return error. */
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear the Flash Control Register */
p_faci_reg->FCR = FCR_CLEAR;
/** Prepare worst case timeout counter */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_write_df;
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/** Check that execute command is completed. */
/** Wait until FRDY is 1 unless timeout occurs. If timeout return error. */
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/* if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If illegal command or programming error reset and return error. */
if ((0U != p_faci_reg->FSTATR2_b.ILGLERR) || (0U != p_faci_reg->FSTATR2_b.PRGERR1))
{
HW_FLASH_LP_reset(p_ctrl);
status = SSP_ERR_WRITE_FAILED;
}
else
{
/** If there are more blocks to write initiate another write operation. If failure return error. */
gp_flash_settings->src_addr += min_program_size;
gp_flash_settings->dest_addr += min_program_size;
gp_flash_settings->total_count--;
if (gp_flash_settings->total_count)
{
HW_FLASH_LP_dataflash_write_operation(p_ctrl, gp_flash_settings->src_addr, gp_flash_settings->dest_addr);
status = SSP_ERR_IN_USE;
}
else
{
status = SSP_SUCCESS;
}
}
/** Return status */
return status;
}
/*******************************************************************************************************************//**
* @brief Initiates the Erase sequence to Erase the # of Data Flash blocks specified by num_blocks, starting with the
* Block containing 'address'.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr - The block containing this address is the first block to be erased.
* @param[in] num_blocks - The # of blocks to be erased.
* @param[in] block_size - The block size for this Flash block.
* @retval None.
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_erase (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_addr, uint32_t num_blocks, uint32_t block_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** Save the current operation parameters. */
gp_flash_settings->dest_addr = start_addr;
gp_flash_settings->total_count = num_blocks;
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_erase_df_block;
gp_flash_settings->current_count = 1U; // Include the one we are doing right here
p_faci_reg->FASR_b.EXS = 0U;
/** Call the data flash erase operation. */
HW_FLASH_LP_dataflash_erase_operation(p_ctrl, gp_flash_settings->dest_addr, block_size);
}
/*******************************************************************************************************************//**
* @brief Execute a single Erase operation on the Low Power Data Flash data.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Starting Code Flash address to erase.
* @param[in] block_size - The block size for this Flash block.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_erase_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t start_addr, uint32_t block_size)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t block_start_addr;
uint32_t block_end_addr;
block_start_addr = start_addr + (uint32_t)DATAFLASH_ADDR_OFFSET; /* Conversion to the P/E address from the read address */
block_end_addr = (block_start_addr + (block_size - 1U));
/** Set the erase start address. */
p_faci_reg->FSARH = (uint16_t) ((block_start_addr >> 16) & 0xFFFFU);
p_faci_reg->FSARL = (uint16_t) (block_start_addr & 0xFFFFU);
/** Set the erase end address. */
p_faci_reg->FEARH = ((block_end_addr >> 16) & 0xFFFFU);
p_faci_reg->FEARL = (uint16_t) (block_end_addr & 0xFFFFU);
/** Execute the erase command. */
p_faci_reg->FCR = FCR_ERASE;
}
/*******************************************************************************************************************//**
* @brief Waits for the erase command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] block_size - The block size for this Flash block.
* @retval SSP_SUCCESS Erase command successfully completed.
* @retval SSP_ERR_IN_USE Erase command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for erase command completion.
* @retval SSP_ERR_WRITE_FAILED Erase failed. Flash could be locked or address could be under access window
* control.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_dataflash_erase_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_size)
{
ssp_err_t status;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If the flash has not completed the software command return error. */
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear Flash Control Register. */
p_faci_reg->FCR = FCR_CLEAR;
/** Prepare worst case timeout counter */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_erase_df_block;
/** Wait until the ready flag is set or timeout. If timeout return error */
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/* Check that execute command is completed. */
/* Wait until FRDY is 1 unless timeout occurs. If timeout return error. */
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/* if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If invalid command or erase error flag is set reset and return error. */
if ((0U != p_faci_reg->FSTATR2_b.ILGLERR) || (0U != p_faci_reg->FSTATR2_b.ERERR))
{
HW_FLASH_LP_reset(p_ctrl);
status = SSP_ERR_WRITE_FAILED;
}
else
{
/** If there are more blocks to erase initiate another erase operation. Otherwise return success. */
gp_flash_settings->dest_addr += block_size;
if (gp_flash_settings->current_count < gp_flash_settings->total_count)
{
HW_FLASH_LP_dataflash_erase_operation(p_ctrl, gp_flash_settings->dest_addr, block_size);
status = SSP_ERR_IN_USE;
}
else
{
status = SSP_SUCCESS;
}
gp_flash_settings->current_count++;
}
return status;
}
/*******************************************************************************************************************//**
* @brief Initiates a Blank check sequence to the Low Power Data Flash data. Address validation has already been
* performed by the caller.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_addr Start address of the Data Flash area to blank check.
* @param[in] end_addr End address of the Data flash area to blank check This address is included in the blank
* check.
* @retval none.
**********************************************************************************************************************/
void HW_FLASH_LP_dataflash_blank_check (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_addr, uint32_t end_addr)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
uint32_t start_addr_idx;
uint32_t end_addr_idx;
start_addr_idx = start_addr + DATAFLASH_ADDR_OFFSET; /* Conversion to the P/E address from the read address */
end_addr_idx = end_addr + DATAFLASH_ADDR_OFFSET; /* Conversion to the P/E address from the read address */
p_faci_reg->FASR_b.EXS = 0U;
/** BlankCheck start address setting */
p_faci_reg->FSARH = (uint16_t) ((start_addr_idx >> 16) & 0xFFFFU);
p_faci_reg->FSARL = (uint16_t) (start_addr_idx & 0xFFFFU);
/** BlankCheck end address setting */
p_faci_reg->FEARH = ((end_addr_idx >> 16) & 0xFFFFU);
p_faci_reg->FEARL = (uint16_t) (end_addr_idx & 0xFFFFU);
/** Execute BlankCheck command */
p_faci_reg->FCR = FCR_BLANKCHECK;
}
/*******************************************************************************************************************//**
* @brief Waits for the blank check command to be completed and verifies the result of the command execution.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS Blank check command successfully completed.
* @retval SSP_ERR_IN_USE Blank check command still in progress.
* @retval SSP_ERR_TIMEOUT Timed out waiting for Blank check command completion.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_dataflash_blank_check_monitor (flash_lp_instance_ctrl_t * const p_ctrl)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If the flash has not completed the software command return error. */
if (1U != p_faci_reg->FSTATR1_b.FRDY)
{
return SSP_ERR_IN_USE;
}
/** Clear the Flash Control Register */
p_faci_reg->FCR = FCR_CLEAR;
/** Prepare worst case timeout counter */
gp_flash_settings->wait_cnt = gp_flash_settings->wait_max_blank_check;
while (0U != p_faci_reg->FSTATR1_b.FRDY)
{
/** Check that execute command is completed. */
/** Wait until FRDY is 1 unless timeout occurs. If timeout return error. */
if (gp_flash_settings->wait_cnt <= (uint32_t)0)
{
/* if FRDY is not set to 0 after max timeout, return error*/
return SSP_ERR_TIMEOUT;
}
gp_flash_settings->wait_cnt--;
}
/** If illegal command reset and return error. */
if (0U != p_faci_reg->FSTATR2_b.ILGLERR)
{
HW_FLASH_LP_reset(p_ctrl);
err = SSP_ERR_WRITE_FAILED;
}
/** Return status. */
return err;
}
/*******************************************************************************************************************//**
* @brief Sets the FPMCR register, used to place the Flash sequencer in Data Flash P/E mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] value - 8 bit value to be written to the FPMCR register.
* @retval none.
**********************************************************************************************************************/
static void HW_FLASH_LP_write_fpmcr (flash_lp_instance_ctrl_t * const p_ctrl, uint8_t value)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
p_faci_reg->FPR = 0xA5U;
p_faci_reg->FPMCR = value;
p_faci_reg->FPMCR = (uint8_t) ~value;
p_faci_reg->FPMCR = value;
if (value == p_faci_reg->FPMCR)
{
__NOP();
}
}
/*******************************************************************************
* Outline : Give the Data Flash HW layer access to the flash settings
* Header : none
* Function Name: set_flash_settings
* Description : Give the Data Flash HW layer access to the flash settings
* Arguments : current_parameters_t *p_current_parameters - Pointer the settings.
* :
* Return Value : none
*******************************************************************************/
void HW_FLASH_LP_data_flash_set_flash_settings (current_parameters_t * const p_current_parameters)
{
gp_flash_settings = p_current_parameters;
}

View File

@ -0,0 +1,107 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_dataflash.h
* Description : Data Flash Control processing for Low Power Flash
**********************************************************************************************************************/
#ifndef R_DATAFLASH_H
#define R_DATAFLASH_H
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/******************************************************************************
* Macro definitions
******************************************************************************/
/* flash mode definition (FENTRYR Register setting)*/
#define FENTRYR_DATAFLASH_PE_MODE (0xAA80U)
#define FENTRYR_READ_MODE (0xAA00U)
/* flash mode definition (FPMCR Register setting)*/
#define DATAFLASH_PE_MODE (0x10U)
#define READ_MODE (0x08U)
#define LVPE_MODE (0x40U)
/* operation definition (FCR Register setting)*/
#define FCR_WRITE (0x81U)
#define FCR_ERASE (0x84U)
#define FCR_BLANKCHECK (0x83U)
#define FCR_CLEAR (0x00U)
#define OPCCR_HIGH_SPEED_MODE (0x00U)
/******************************************************************************
* Typedef definitions
******************************************************************************/
/**
* @struct r_dataflash_data_t
* DATAFLASH information values
*/
typedef struct R_DATAFLASH_DATA_T
{
uint32_t start_addr; /* start address (Erase) or Ram Source for Write, Dest for read */
uint32_t end_addr; /* end address (Erase), or Flash Start address which will be read/written */
uint32_t write_cnt; /* bytes remaining to do */
} r_dataflash_data_t;
typedef struct R_DATAFLASH_ERASE_T
{
uint32_t start_addr; /* start address (Erase) or Ram Source for Write, Dest for read */
uint32_t end_addr; /* end address (Erase), or Flash Start address which will be read/written */
uint32_t write_cnt; /* bytes remaining to do */
} r_dataflash_erase_t;
/******************************************************************************
* Exported global variables
******************************************************************************/
void HW_FLASH_LP_dataflash_enable (flash_lp_instance_ctrl_t * const p_ctrl);
void HW_FLASH_LP_dataflash_enter_pe_mode (flash_lp_instance_ctrl_t * const p_ctrl);
ssp_err_t HW_FLASH_LP_dataflash_enter_read_mode (flash_lp_instance_ctrl_t * const p_ctrl);
void HW_FLASH_LP_dataflash_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address,
uint32_t dest_start_address,
uint32_t num_bytes,
uint32_t min_program_size);
void HW_FLASH_LP_dataflash_write_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t psrc_addr, uint32_t dest_addr);
ssp_err_t HW_FLASH_LP_dataflash_write_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t min_program_size);
void HW_FLASH_LP_dataflash_erase (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_addr, uint32_t num_blocks, uint32_t block_size);
void HW_FLASH_LP_dataflash_erase_operation (flash_lp_instance_ctrl_t * const p_ctrl, const uint32_t block_start_addr, uint32_t block_size);
ssp_err_t HW_FLASH_LP_dataflash_erase_monitor (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_size);
void HW_FLASH_LP_dataflash_blank_check (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_addr, uint32_t end_addr);
ssp_err_t HW_FLASH_LP_dataflash_blank_check_monitor (flash_lp_instance_ctrl_t * const p_ctrl);
void HW_FLASH_LP_data_flash_set_flash_settings(current_parameters_t * const p_current_parameters);
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* R_DATAFLASH_H */

View File

@ -0,0 +1,106 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_flash_common.c
* Description : Common functions used by both the Code and Data Low Power Flash modules
**********************************************************************************************************************/
/******************************************************************************
* Includes <System Includes> , Project Includes
******************************************************************************/
#include "bsp_api.h"
#include "r_flash_lp.h"
#include "../hw_flash_lp_private.h"
#include "r_flash_cfg.h"
#include "hw_flash_common.h"
#include "hw_dataflash.h"
#include "hw_codeflash.h"
#include "hw_codeflash_extra.h"
/*******************************************************************************************************************//**
* @addtogroup FLASH
* @{
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @} (end FLASH)
**********************************************************************************************************************/
/******************************************************************************
* Macro definitions
******************************************************************************/
#if defined(__ICCARM__)
#define BSP_ATTRIBUTE_STACKLESS __stackless
#elif defined(__GNUC__)
/*LDRA_INSPECTED 293 s - This is an allowed exception to LDRA standard 293 S "Non ANSI/ISO construct used. "*/
#define BSP_ATTRIBUTE_STACKLESS __attribute__((naked))
#endif
/******************************************************************************
* Private global variables and functions
******************************************************************************/
BSP_ATTRIBUTE_STACKLESS static void HW_FLASH_LP_delay_loop (uint32_t n) PLACE_IN_RAM_SECTION;
// Roughly 4 cycles per loop
#define DELAY_LOOP_CYCLES 4U
BSP_ATTRIBUTE_STACKLESS static void HW_FLASH_LP_delay_loop (uint32_t n)
{
SSP_PARAMETER_NOT_USED(n); /// prevent compiler 'unused' warning
__asm volatile ("label1:\n"
#if defined(__ICCARM__)
" subs r0, #1 \n" ///< 1 cycle
#elif defined(__GNUC__)
" sub r0, r0, #1 \n" ///< 1 cycle
#endif
"cmp r0, #0\n" // 1 cycle
/* CM0 has a different instruction set */
#if defined(__CORE_CM0PLUS_H_GENERIC) || defined(__CORE_ARMV8MBL_H_GENERIC)
" bne label1 \n" ///< 2 cycles
#else
" bne.n label1 \n" ///< 2 cycles
#endif
"bx lr\n"); // ~2 cycles
}
/*******************************************************************************
* Outline : Function that specifies the execution time
* Header : none
* Function Name: r_flash_delay_us
* Description : The number of loops is calculated based on the execution time (micro secs)
* : and the sytem clock (ICLK) frequency, and the intrinsic function
* : that specifies the number of loops is called.
* Arguments : us : Execution time
* : mhz : ICLK frequency (in Mhz)
* Return Value : none
*******************************************************************************/
void HW_FLASH_LP_delay_us (uint32_t us, uint32_t mhz)
{
uint32_t loop_cnt;
// @12 MHz, one loop is 332 ns. A delay of 5 us would require 15 loops. 15 * 332 = 4980 ns or ~ 5us
/* Calculation of a loop count */
loop_cnt = ((us * mhz) / DELAY_LOOP_CYCLES);
if (loop_cnt > 0U)
{
HW_FLASH_LP_delay_loop(loop_cnt);
}
}

View File

@ -0,0 +1,63 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_flash_common.h
* Description : Common functions used by both the Code and Data Low Power Flash modules
**********************************************************************************************************************/
#ifndef R_FLASH_COMMON_H_
#define R_FLASH_COMMON_H_
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/******************************************************************************
* Includes <System Includes> , "Project Includes"
******************************************************************************/
/******************************************************************************
* Typedef definitions
******************************************************************************/
/* Wait Process definition */
#define WAIT_TDIS (3U)
#define WAIT_TMS_MID (4U)
#define WAIT_TMS_HIGH (6U)
#define WAIT_TDSTOP (6U)
#define MHZ (1000000U)
#define KHZ (1000U)
/* Flash information */
/* Used for DataFlash */
#define DATAFLASH_READ_BASE_ADDR (0x40100000U)
#define DATAFLASH_WRITE_BASE_ADDR (0xFE000000U)
#define DATAFLASH_ADDR_OFFSET (DATAFLASH_WRITE_BASE_ADDR - DATAFLASH_READ_BASE_ADDR)
void HW_FLASH_LP_delay_us (uint32_t us, uint32_t mhz) PLACE_IN_RAM_SECTION;
void HW_FLASH_LP_set_flash_settings (R_FACI_Type * p_faci_reg, current_parameters_t * p_current_parameters);
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* R_FLASH_COMMON_H_ */
/* End of File */

View File

@ -0,0 +1,703 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_flash_lp.c
* Description : LLD Interface for the Low power Flash peripheral on SC32 MCUs.
**********************************************************************************************************************/
/***********************************************************************************************************************
* Includes
**********************************************************************************************************************/
/***********************************************************************************************************************
* Includes
**********************************************************************************************************************/
#include "bsp_api.h"
#include "r_flash_lp.h"
#include "hw_flash_lp_private.h"
#include "r_flash_cfg.h"
#include "r_cgc_api.h"
#include "r_cgc.h"
#include "flash_lp_core/hw_dataflash.h"
#include "flash_lp_core/hw_codeflash.h"
#include "flash_lp_core/hw_codeflash_extra.h"
/*******************************************************************************************************************//**
* @addtogroup FLASH
* @{
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @} (end FLASH)
**********************************************************************************************************************/
/***********************************************************************************************************************
* Typedef definitions
**********************************************************************************************************************/
/***********************************************************************************************************************
* Macro definitions
**********************************************************************************************************************/
/* The number of CPU cycles per each timeout loop. */
#ifndef R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP
#if defined(__GNUC__)
#define R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP (6U)
#elif defined(__ICCARM__)
#define R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP (6U)
#endif
#endif
#define R_FLASH_LP_HZ_IN_MHZ (1000000U)
/***********************************************************************************************************************
* Private function prototypes
**********************************************************************************************************************/
/***********************************************************************************************************************
* Private global variables
**********************************************************************************************************************/
static current_parameters_t * gp_flash_parameters = NULL; // passed in via flash_init()
static inline bool HW_FLASH_LP_frdyi_df_bgo_write (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data);
static inline bool HW_FLASH_LP_frdyi_df_bgo_erase (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data);
static inline bool HW_FLASH_LP_frdyi_df_bgo_blankcheck (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data);
/***********************************************************************************************************************
* Functions
**********************************************************************************************************************/
/*******************************************************************************************************************//**
* @brief This function enables or disables the Flash interrupt. The flash interrupt, if enabled, is called when a
* Flash operation completes, or when an Error condition is detected. If the caller has provided a callback
* function as part of the provided p_cfg pointer, then that function will be called as a result of the
* interrupt.
* @param[in] state Control for the FLASH device context.
* @param[in] p_cfg Pointer to the FLASH configuration structure.
* @param[in] irq Flash interrupt irq number.
* @retval SSP_SUCCESS Successful.
* @retval SSP_ERR_IRQ_BSP_DISABLED Caller is requesting BGO but the Flash interrupts are not enabled.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_irq_cfg (bool state, flash_cfg_t const * const p_cfg, IRQn_Type irq)
{
SSP_PARAMETER_NOT_USED(state);
/** If BGO is being used then we require the Flash Rdy interrupt be enabled. If it
* is not enabled then we are not going to be doing BGO and we won't generate an ISR routine */
if (SSP_INVALID_VECTOR != irq)
{
/** Enable the Interrupt */
if (true == state)
{
/** Enable FCU interrupts if callback is not null, clear the Interrupt Request bit */
NVIC_ClearPendingIRQ(irq);
R_BSP_IrqStatusClear(irq);
NVIC_EnableIRQ(irq);
}
/** Disable the Interrupts */
else
{
/** Disable interrupt in ICU*/
NVIC_DisableIRQ(irq);
/** Clear the Interrupt Request bit */
R_BSP_IrqStatusClear(irq);
}
return SSP_SUCCESS;
}
else
{
/** The Flash Interrupt has not been enabled. If the caller is requesting BGO then we'll flag this as an error. */
if (p_cfg->data_flash_bgo == true)
{
return SSP_ERR_IRQ_BSP_DISABLED;
}
else
{
return SSP_SUCCESS;
}
}
}
/*******************************************************************************************************************//**
* @brief This function will initialize the FCU and set the FCU Clock based on the current FCLK frequency.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in, out] p_current_parameters Pointer to the g_current_parameters structure created by the HLD layer.
**********************************************************************************************************************/
void HW_FLASH_LP_init (flash_lp_instance_ctrl_t * const p_ctrl, current_parameters_t * p_current_parameters)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
gp_flash_parameters = p_current_parameters; // our copy from now on
gp_flash_parameters->current_operation = FLASH_OPERATION_FCU_INIT;
/* Round up the frequency to a whole number */
uint32_t system_clock_freq_mhz = (gp_flash_parameters->system_clock_freq + (R_FLASH_LP_HZ_IN_MHZ - 1)) / R_FLASH_LP_HZ_IN_MHZ;
gp_flash_parameters->flash_clock_freq = gp_flash_parameters->flash_clock_freq / 1000000; // Scale it down
gp_flash_parameters->system_clock_freq = gp_flash_parameters->system_clock_freq / 1000000; // Scale it down
/* According to HW Manual the Max Programming Time for 4 bytes(S124/S128) or 8 bytes(S1JA/S3A*)(ROM)
* is 1411us. This is with a FCLK of 1MHz. The calculation below
* calculates the number of ICLK ticks needed for the timeout delay.
*/
gp_flash_parameters->wait_max_write_cf = (uint32_t) (1411 * system_clock_freq_mhz)/R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
/* According to HW Manual the Max Programming Time for 1 byte
* (Data Flash) is 886us. This is with a FCLK of 4MHz. The calculation
* below calculates the number of ICLK ticks needed for the timeout delay.
*/
gp_flash_parameters->wait_max_write_df = (uint32_t) (886 * system_clock_freq_mhz)/R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
/* According to HW Manual the Max Blank Check time for 2 bytes (S12*) or 8 bytes (S1JA/S3A*)
* (Code Flash) is 87.7 usec. This is with a FCLK of 1MHz. The calculation
* below calculates the number of ICLK ticks needed for the timeout delay.
*/
gp_flash_parameters->wait_max_blank_check = (uint32_t) (88 * system_clock_freq_mhz)/R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
/* According to HW Manual the Max Erasure Time for a 1KB block (S12*) or 2KB bytes (S1JA/S3A*) is
* around 289ms. This is with a FCLK of 1MHz. The calculation below
* calculates the number of ICLK ticks needed for the timeout delay.
*/
gp_flash_parameters->wait_max_erase_cf_block = (uint32_t) (289000 * system_clock_freq_mhz)/R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
/* According to HW Manual the Max Erasure Time for a 1KB Data Flash block is
* around 299ms. This is with a FCLK of 4MHz. The calculation below
* calculates the number of ICLK ticks needed for the timeout delay.
*/
gp_flash_parameters->wait_max_erase_df_block = (uint32_t) (299000 * system_clock_freq_mhz)/R_FLASH_LP_CYCLES_MINIMUM_PER_TIMEOUT_LOOP;
/** Per the Flash spec, update the FLWAIT register if FCLK is being changed */
p_faci_reg->FLWAITR = 0U;
}
/*******************************************************************************************************************//**
* @brief This function erases a specified number of Code or Data Flash blocks
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] block_address The starting address of the first block to erase.
* @param[in] num_blocks The number of blocks to erase.
* @param[in] block_size The Flash block size.
* @retval SSP_SUCCESS Successfully erased (non-BGO) mode or operation successfully started (BGO).
* @retval SSP_ERR_ERASE_FAILED Status is indicating a Erase error.
* @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal
* command.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_erase (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_address, uint32_t num_blocks, uint32_t block_size)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
gp_flash_parameters->block_size = block_size;
/* We're already in the appropriate P/E mode from the caller */
/** If the module is configured for Data Flash P/E mode */
if (p_faci_reg->FENTRYR == 0x0080U)
{
/** Erase a block of data flash. */
HW_FLASH_LP_dataflash_erase(p_ctrl, block_address, num_blocks, block_size); // Set the start and end and do first block
/** If configured for Blocking mode then don't return until the entire operation is complete */
if (gp_flash_parameters->bgo_enabled_df == false)
{
do
{
/** Waits for the erase commands to be completed and verifies the result of the command execution. */
err = HW_FLASH_LP_dataflash_erase_monitor(p_ctrl, block_size);
} while (SSP_ERR_IN_USE == err);
}
}
#if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1)
/** Else if the module is configured for code flash P/E mode */
else if (p_faci_reg->FENTRYR == 0x0001U)
{
/** Erase a block of code flash */
HW_FLASH_LP_codeflash_erase(p_ctrl, block_address, num_blocks, block_size); // Set the start and end and do first block
/* Code Flash is always blocking mode */
do
{
/** Waits for the erase commands to be completed and verifies the result of the command execution. */
err = HW_FLASH_LP_codeflash_erase_monitor(p_ctrl, block_size);
} while (SSP_ERR_IN_USE == err);
}
#endif /* if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1) */
else
{
/** Otherwise the module is not configured for data or code flash P/E mode. return failure */
/* should never get here */
return SSP_ERR_ERASE_FAILED;
}
return err;
}
/*******************************************************************************************************************//**
* @brief This function writes a specified number of bytes to Code or Data Flash.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] src_start_address The starting address of the first byte (from source) to write.
* @param[in] dest_start_address The starting address of the Flash (to destination) to write.
* @param[in] num_bytes The number of bytes to write.
* @param[in] min_program_size The minimum Flash programming size.
*
* @retval SSP_SUCCESS Data successfully written (non-BGO) mode or operation successfully started (BGO).
* @retval SSP_ERR_IN_USE Command still executing.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation. This
* may be returned if the requested Flash area is not blank.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the Flash sequencer to become ready.
* @retval SSP_ERR_PE_FAILURE Unable to enter Programming mode. Flash may be locked (FSPR bit).
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address,
uint32_t dest_start_address,
uint32_t num_bytes,
uint32_t min_program_size)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
gp_flash_parameters->dest_addr = dest_start_address;
gp_flash_parameters->src_addr = src_start_address;
gp_flash_parameters->current_count = (uint32_t)0;
/** If flash is in PE mode for Data Flash. */
if (p_faci_reg->FENTRYR == 0x0080U)
{
gp_flash_parameters->total_count = num_bytes; // NPP7 and NPP4 both have DF write size of 1.
/** Start the write operation */
HW_FLASH_LP_dataflash_write(p_ctrl, src_start_address, dest_start_address, num_bytes, min_program_size);
/** If configured for Blocking mode then don't return until the entire operation is complete */
if (gp_flash_parameters->bgo_enabled_df == false)
{
do
{
/** Wait for the write commands to be completed and verifies the result of the command execution. */
err = HW_FLASH_LP_dataflash_write_monitor(p_ctrl, min_program_size);
} while (SSP_ERR_IN_USE == err);
/** Disable P/E mode for data flash. */
HW_FLASH_LP_dataflash_enter_read_mode(p_ctrl);
}
}
#if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1)
/** If flash is in P/E mode for code flash */
else if (p_faci_reg->FENTRYR == 0x0001U)
{
uint32_t temp = min_program_size;
uint32_t right_shift = 0U;
while (1U != temp)
{
temp >>= 1;
right_shift++;
}
/** Calculate the total number of writes. */
/* This is done with right shift instead of division to avoid using the division library, which would be in flash
* and cause a jump from RAM to flash. */
gp_flash_parameters->total_count = num_bytes >> right_shift;
/** Start the write operation */
HW_FLASH_LP_codeflash_write(p_ctrl, src_start_address, dest_start_address, num_bytes, min_program_size);
/** Code Flash is always blocking mode, so we don't return until the entire operation is complete */
do
{
err = HW_FLASH_LP_codeflash_write_monitor(p_ctrl, min_program_size);
} while (SSP_ERR_IN_USE == err);
/** Disable P/E mode for code flash. */
HW_FLASH_LP_codeflash_enter_read_mode(p_ctrl); // We're done, return to read mode
}
#endif /* if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1) */
else
{
/** Otherwise return error. */
//Flash locked (FSPR bit?)
return SSP_ERR_PE_FAILURE;
}
return err;
}
/*******************************************************************************************************************//**
* @brief This function checks if the specified Data Flash address range is blank.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] start_address The starting address of the Flash area to blank check.
* @param[in] num_bytes Specifies the number of bytes that need to be checked.
* @param[out] result Pointer that will be populated by the API with the results of the blank check
* operation in non-BGO (blocking) mode. In this case the blank check operation
* completes here and the result is returned. In Data Flash BGO mode the blank check
* operation is only started here and the result obtained later when the
* supplied callback routine is called.
* @retval SSP_SUCCESS Blankcheck operation completed with result in result,
* or blankcheck started and in-progess (BGO mode).
* @retval SSP_ERR_ERASE_FAILED Status is indicating an erase error. Possibly from a prior operation.
* @retval SSP_ERR_CMD_LOCKED FCU is in locked state, typically as a result of having received an illegal command.
* @retval SSP_ERR_WRITE_FAILED Status is indicating a Programming error for the requested operation.
* @retval SSP_ERR_TIMEOUT Timed out waiting for the FCU to become ready.
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_blankcheck (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_address, uint32_t num_bytes, flash_result_t * result)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/* We're already in the appropriate P/E mode from the caller */
/** If flash is configured for data flash P/E mode */
if (p_faci_reg->FENTRYR == 0x0080U)
{
/** Execute blank check command. */
HW_FLASH_LP_dataflash_blank_check(p_ctrl, start_address, (start_address + num_bytes) - 1); // We want to blank check 0
// - num_bytes-1
/** If in DF BGO mode, exit here; remaining processing if any will be done in ISR */
if (gp_flash_parameters->bgo_enabled_df == true)
{
*result = FLASH_RESULT_BGO_ACTIVE;
return err;
}
/** If not in DF BGO mode wait for the command to complete. */
do
{
err = HW_FLASH_LP_dataflash_blank_check_monitor(p_ctrl);
} while (SSP_ERR_IN_USE == err);
/** If successful check the result of the blank check. */
if (err == SSP_SUCCESS)
{
if (0U != p_faci_reg->FSTATR00_b.BCERR0) // Tested Flash Area is not blank
{
*result = FLASH_RESULT_NOT_BLANK;
}
else
{
*result = FLASH_RESULT_BLANK;
}
/** Reset the flash. */
HW_FLASH_LP_reset(p_ctrl); // Make sure we clear the BCERR bit that reflects the result of
// our blank check
/** Return the data flash to P/E mode. */
HW_FLASH_LP_dataflash_enter_read_mode(p_ctrl); // We're done, return to read mode
}
}
/** If flash is configured for code flash P/E mode */
else if (p_faci_reg->FENTRYR == 0x0001U)
{
/** Give the initial (and possibly only) Blank check command to the FACI. */
err = HW_FLASH_LP_codeflash_blank_check(p_ctrl, start_address, num_bytes);
if (err == SSP_SUCCESS)
{
do
{
/** Wait for the blank check to complete and return result in control block. */
err = HW_FLASH_LP_codeflash_blank_check_monitor(p_ctrl);
} while (SSP_ERR_IN_USE == err);
/** If succeessful reset the flash and put the code flash into read mode. */
if (err == SSP_SUCCESS)
{
*result = gp_flash_parameters->bc_result;
HW_FLASH_LP_reset(p_ctrl); // Make sure we clear the BCERR bit that reflects the result of our bc
HW_FLASH_LP_codeflash_enter_read_mode(p_ctrl); // We're done, return to read mode
}
}
}
/** Return status. Blank status is in result. */
return err;
}
/*******************************************************************************************************************//**
* @brief This function switches the peripheral to P/E mode for Code Flash or Data Flash.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] flash_type Specifies Code or Data Flash.
* Valid selections are: FLASH_TYPE_CODE_FLASH or FLASH_TYPE_DATA_FLASH
* @retval SSP_SUCCESS Successfully entered P/E mode.
* @retval SSP_ERR_PE_FAILURE Failed to enter P/E mode
* @retval SSP_ERR_INVALID_ARGUMENT Supplied flash_type was something other than FLASH_TYPE_CODE_FLASH or
* FLASH_TYPE_DATA_FLASH, or Code Flash Programming is not enabled and a request to
* is for a CF operation.
*
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_pe_mode_enter (flash_lp_instance_ctrl_t * const p_ctrl, flash_type_t flash_type)
{
ssp_err_t err = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If the flas type is data flash put the data flash in PE mode. */
if (flash_type == FLASH_TYPE_DATA_FLASH)
{
HW_FLASH_LP_dataflash_enter_pe_mode(p_ctrl); // Sets PCKA clock
/** Verify that we actually did enter DF P/E mode. If not return error */
if (p_faci_reg->FENTRYR != 0x0080U)
{
err = SSP_ERR_PE_FAILURE;
}
}
#if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1)
/** If the flash type is code flash put the code flash in PE mode */
else if (flash_type == FLASH_TYPE_CODE_FLASH)
{
HW_FLASH_LP_codeflash_enter_pe_mode(p_ctrl);
/** Verify that we actually did enter CF P/E mode. If not return error */
if (p_faci_reg->FENTRYR != 0x0001U)
{
err = SSP_ERR_PE_FAILURE;
}
}
#endif /* if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1) */
else
{
/** If neither code flash or data flash command return error. */
err = SSP_ERR_INVALID_ARGUMENT;
}
return err;
}
/*******************************************************************************************************************//**
* @brief This function switches the peripheral from P/E mode for Code Flash or Data Flash to Read mode.
* @param[in] p_ctrl Pointer to the Flash control block
* @retval SSP_SUCCESS Successfully entered P/E mode.
* @retval SSP_ERR_PE_FAILURE Failed to exited P/E mode
* @retval SSP_FLASH_ERR_PARAMETERS Supplied flash_type was something other than FLASH_TYPE_CODE_FLASH or
* FLASH_TYPE_DATA_FLASH.
*
**********************************************************************************************************************/
ssp_err_t HW_FLASH_LP_pe_mode_exit (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If device is configured for P/E mode for data flash exit P/E mode */
if (p_faci_reg->FENTRYR == 0x0080U)
{
HW_FLASH_LP_dataflash_enter_read_mode(p_ctrl);
}
#if (FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE == 1)
/** Otherwise if device is configured for P/E mode for code flash exit P/E mode. */
else if (p_faci_reg->FENTRYR == 0x0001U)
{
HW_FLASH_LP_codeflash_enter_read_mode(p_ctrl);
}
#endif
return (SSP_SUCCESS);
}
/*******************************************************************************************************************//**
* @brief This function resets the Flash sequencer.
* @param[in] p_ctrl Pointer to the Flash control block
**********************************************************************************************************************/
void HW_FLASH_LP_reset (flash_lp_instance_ctrl_t * const p_ctrl)
{
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** If not currently in PE mode then enter P/E mode. */
if (p_faci_reg->FENTRYR == 0x0000UL)
{
/* Enter P/E mode so that we can execute some FACI commands. Either Code or Data Flash P/E mode would work
* but Code Flash P/E mode requires FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE ==1, which may not be true */
HW_FLASH_LP_pe_mode_enter(p_ctrl, FLASH_TYPE_DATA_FLASH);
}
/** Reset the flash. */
p_faci_reg->FRESETR_b.FRESET = 1U;
p_faci_reg->FRESETR_b.FRESET = 0U;
/** Transition to Read mode */
HW_FLASH_LP_pe_mode_exit(p_ctrl);
/** If DF BGO is enabled and we have an interrupt defined for FACI, re-enable it */
if (gp_flash_parameters->bgo_enabled_df == true)
{
/** Indicate that we just reset the FCU */
gp_flash_parameters->current_operation = FLASH_OPERATION_FCU_RESET;
}
}
/*******************************************************************************************************************//**
* @brief Handle the FACI frdyi interrupt when the operation is Data Flash BGO write.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] p_cb_data Pointer to the Flash callback event structure.
* @retval true, when operation is completed or error has occurred.
*
**********************************************************************************************************************/
static inline bool HW_FLASH_LP_frdyi_df_bgo_write (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data)
{
bool operation_complete = false;
ssp_err_t result = SSP_SUCCESS;
/** We are handling the interrupt indicating the last write operation has completed. */
/** Whether we are done or not we want to check the status */
result = HW_FLASH_LP_dataflash_write_monitor(p_ctrl, gp_flash_parameters->min_pgm_size);
if ((result != SSP_SUCCESS) && (result != SSP_ERR_IN_USE))
{
HW_FLASH_LP_reset(p_ctrl);
p_cb_data->event = FLASH_EVENT_ERR_FAILURE; ///< Pass result back to callback
operation_complete = true;
}
else
{
/*If there are still bytes to write*/
if (gp_flash_parameters->total_count == (uint32_t)0)
{
p_cb_data->event = FLASH_EVENT_WRITE_COMPLETE;
operation_complete = true;
}
}
return(operation_complete);
}
/*******************************************************************************************************************//**
* @brief Handle the FACI frdyi interrupt when the operation is Data Flash BGO erase.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] p_cb_data Pointer to the Flash callback event structure.
* @retval true, when operation is completed or error has occurred.
*
**********************************************************************************************************************/
static inline bool HW_FLASH_LP_frdyi_df_bgo_erase (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data)
{
bool operation_complete = false;
ssp_err_t result = SSP_SUCCESS;
/** We are handling the interrupt indicating the last erase operation has completed. */
/** Whether we are done or not we want to check the status */
result = HW_FLASH_LP_dataflash_erase_monitor(p_ctrl, gp_flash_parameters->block_size);
if ((result != SSP_SUCCESS) && (result != SSP_ERR_IN_USE))
{
HW_FLASH_LP_reset(p_ctrl);
p_cb_data->event = FLASH_EVENT_ERR_FAILURE; ///< Pass result back to callback
operation_complete = true;
}
else
{
if (gp_flash_parameters->current_count > gp_flash_parameters->total_count)
{
p_cb_data->event = FLASH_EVENT_ERASE_COMPLETE;
operation_complete = true;
}
}
return(operation_complete);
}
/*******************************************************************************************************************//**
* @brief Handle the FACI frdyi interrupt when the operation is Data Flash BGO blankcheck.
* @param[in] p_ctrl Pointer to the Flash control block
* @param[in] p_cb_data Pointer to the Flash callback event structure.
* @retval true, when operation is completed or error has occurred.
*
**********************************************************************************************************************/
static inline bool HW_FLASH_LP_frdyi_df_bgo_blankcheck (flash_lp_instance_ctrl_t *p_ctrl, flash_callback_args_t *p_cb_data)
{
bool operation_complete = false;
ssp_err_t result = SSP_SUCCESS;
R_FACI_Type * p_faci_reg = (R_FACI_Type *) p_ctrl->p_reg;
/** We are handling the interrupt indicating the last blank check operation has completed. */
/** Whether we are done or not we want to check the status */
result = HW_FLASH_LP_dataflash_blank_check_monitor(p_ctrl);
/// All of the following are valid returns.
if ((result != SSP_SUCCESS) && (result != SSP_ERR_IN_USE))
{
HW_FLASH_LP_reset(p_ctrl);
p_cb_data->event = FLASH_EVENT_ERR_FAILURE; ///< Pass result back to callback
operation_complete = true;
}
else
{
operation_complete = true;
p_cb_data->event = FLASH_EVENT_BLANK;
if (p_faci_reg->FSTATR00_b.BCERR0 == 1U)
{
p_cb_data->event = FLASH_EVENT_NOT_BLANK;
}
}
return(operation_complete);
}
/*******************************************************************************************************************//**
* @brief FLASH ready interrupt routine.
*
* @details This function implements the FLASH ready isr. The function clears the interrupt request source on entry
* populates the callback structure with the relevant event, and providing
* a callback routine has been provided, calls the callback function with the event. <br>
*
**********************************************************************************************************************/
void fcu_frdyi_isr (void)
{
SF_CONTEXT_SAVE
flash_callback_args_t cb_data;
bool operation_completed = false;
ssp_vector_info_t * p_vector_info = NULL;
R_SSP_VectorInfoGet(R_SSP_CurrentIrqGet(), &p_vector_info);
flash_lp_instance_ctrl_t * p_ctrl = (flash_lp_instance_ctrl_t *) *(p_vector_info->pp_ctrl);
/** Clear the Interrupt Request*/
R_BSP_IrqStatusClear(R_SSP_CurrentIrqGet());
/** Continue the current operation. If unknown operation set callback event to failure. */
if (FLASH_OPERATION_DF_BGO_WRITE == gp_flash_parameters->current_operation)
{
operation_completed = HW_FLASH_LP_frdyi_df_bgo_write(p_ctrl, &cb_data);
}
else if ((FLASH_OPERATION_DF_BGO_ERASE == gp_flash_parameters->current_operation))
{
operation_completed = HW_FLASH_LP_frdyi_df_bgo_erase(p_ctrl, &cb_data);
}
else if (FLASH_OPERATION_DF_BGO_BLANKCHECK == gp_flash_parameters->current_operation)
{
operation_completed = HW_FLASH_LP_frdyi_df_bgo_blankcheck(p_ctrl, &cb_data);
}
else
{
/* This case could only be reached by a memory corruption of some type. */
cb_data.event = FLASH_EVENT_ERR_FAILURE;
}
/** If the operation completed exit read mode, release the flash, and call the callback if available. */
if (operation_completed == true)
{
/* finished current operation. Exit P/E mode*/
HW_FLASH_LP_pe_mode_exit(p_ctrl);
/* Release lock and Set current state to Idle*/
flash_ReleaseState();
gp_flash_parameters->current_operation = FLASH_OPERATION_IDLE;
if (NULL != p_ctrl->p_callback)
{
/** Set data to identify callback to user, then call user callback. */
p_ctrl->p_callback(&cb_data);
}
}
SF_CONTEXT_RESTORE
} /* End of function fcu_frdyi_isr() */

View File

@ -0,0 +1,200 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
/**********************************************************************************************************************
* File Name : hw_flash_lp_private.h
* Description : FLASH LLD header file for Low power Flash.
**********************************************************************************************************************/
#include "r_flash_lp.h"
#ifndef HW_FLASH_LP_PRIVATE_H
#define HW_FLASH_LP_PRIVATE_H
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/**********************************************************************************************************************
* Includes
**********************************************************************************************************************/
/**********************************************************************************************************************
* Macro definitions
**********************************************************************************************************************/
/** The maximum timeout for commands is 100usec when FCLK is 16 MHz i.e. 1600 FCLK cycles.
* Assuming worst case of ICLK at 240 MHz and FCLK at 4 MHz, and optimization set to max such that
* each count decrement loop takes only 5 cycles, then ((240/4)*1600)/5 = 19200 */
#define FLASH_FRDY_CMD_TIMEOUT (19200)
/** Time that it would take for the Data Buffer to be empty (DBFULL Flag) is 90 FCLK cycles.
* Assuming worst case of ICLK at 240 MHz and FCLK at 4 MHz, and optimization set to max such that
* each count decrement loop takes only 5 cycles, then ((240/4)*90)/5 = 1080 */
#define FLASH_DBFULL_TIMEOUT (1080)
/***********************************************************************************************************************
* Typedef definitions
**********************************************************************************************************************/
/** Flash software lock states */
typedef enum e_flash_states_t
{
FLASH_STATE_UNINITIALIZED = 0,
FLASH_STATE_INITIALIZATION,
FLASH_STATE_READY,
FLASH_STATE_WRITING,
FLASH_STATE_ERASING,
FLASH_STATE_BLANK_CHECK,
FLASH_STATE_ACCESS_WINDOW,
FLASH_STATE_STARTUP_AREA,
FLASH_STATE_ID_CODE,
FLASH_UPDATE_FCLK
} flash_states_t;
/** Flash types */
typedef enum e_flash_type
{
FLASH_TYPE_CODE_FLASH = 0, ///< Operation is referencing Code Flash
FLASH_TYPE_DATA_FLASH ///< Operation is referencing Data Flash
} flash_type_t;
/** Possible Flash operation states */
typedef enum e_flash_operation
{
FLASH_OPERATION_INVALID,
FLASH_OPERATION_IDLE,
FLASH_OPERATION_CF_ERASE,
FLASH_OPERATION_CF_WRITE,
FLASH_OPERATION_DF_ERASE,
FLASH_OPERATION_DF_WRITE,
FLASH_OPERATION_DF_BLANKCHECK,
FLASH_OPERATION_CF_BLANKCHECK,
FLASH_OPERATION_DF_BGO_WRITE,
FLASH_OPERATION_DF_BGO_ERASE,
FLASH_OPERATION_DF_BGO_BLANKCHECK,
FLASH_OPERATION_FCU_INIT,
FLASH_OPERATION_FCU_RESET
} flash_operation_t;
/** Parameters reflecting current in progress Flash operation */
typedef struct st_current_parameters
{
uint32_t src_addr; ///< Source address for operation in progress
uint32_t dest_addr; ///< Destination address for operation in progress
uint32_t total_count; ///< total number of bytes to write/erase
uint32_t current_count; ///< bytes of total completed
flash_operation_t current_operation; ///< Operation in progress, ie. FLASH_OPERATION_CF_ERASE
bool bgo_enabled_df; ///< Data Flash BGO operation enable/disable
uint32_t min_pgm_size; ///< Minimum # of bytes that can be programmed, as defined for the
///< part, usually differs for CF and DF
uint32_t block_size; ///< Minimum # of bytes that can be read or erased
uint32_t cf_memory_st_addr; ///< Starting memory address for Code Flash
uint32_t df_memory_st_addr; ///< Starting memory address for Data Flash
uint8_t flash_cf_macros; ///< The number of implemented HW Code Flash macros.
uint32_t cf_macro_size; ///< The size of the implemented Code Flash macro
uint32_t wait_cnt; ///< Worst case wait time for operation completion
uint32_t wait_max_erase_df_block; ///< Worst case erase time for DF block
uint32_t wait_max_erase_cf_block; ///< Worst case erase time for large CF block
uint32_t wait_max_blank_check; ///< Worst case blankcheck time for minimum blank check size
uint32_t wait_max_write_df; ///< Worst case write time for DF minimum write size
uint32_t wait_max_write_cf; ///< Worst case write time for CF minimum write size
uint32_t flash_clock_freq; ///< Flash clock frequency in Hz
uint32_t system_clock_freq; ///< System clock frequency in Hz
flash_result_t bc_result; ///< Overall result of possible multi operation blankcheck.
} current_parameters_t;
/** Flash block details */
typedef struct st_flash_block_info
{
uint32_t block_section_st_addr; ///< starting address for this block section (blocks of this size)
uint32_t block_section_end_addr; ///< ending address for this block section (blocks of this size)
uint32_t memory_end_addr; ///< ending address for the memory itself (code or data)
uint32_t block_size; ///< Size of this block
uint32_t min_program_size; ///< minimum program size (bytes)
uint32_t num_blocks; ///< number of blocks at this size
uint32_t total_blocks; ///< total number of blocks of this type
uint32_t this_block_st_addr; ///< starting address for this block (for queried address)
uint32_t this_block_end_addr; ///< ending address for this block (blocks of this size)
uint32_t this_block_number; ///< zero based block number for this address
bool is_code_flash_addr; ///< true if queried address is a Code Flash address
flash_type_t flash_type; ///< target operation is for FLASH_TYPE_CODE_FLASH or FLASH_TYPE_DATA_FLASH
} flash_block_info_t;
/** Flash macro information */
typedef struct st_flash_lp_macro_info
{
uint32_t macro_st_addr; ///< starting address for this macro
uint32_t macro_end_addr; ///< ending address for this macro
uint32_t macro_size; ///< number of bytes in this macro
uint32_t total_macros; ///< total number of macros for this device and flash type (Code or Data)
uint32_t allowed_bytes; ///< number of the requested bytes that may be provided to blancheck for this macro
} flash_lp_macro_info_t;
/**********************************************************************************************************************
* Public Functions
**********************************************************************************************************************/
/** NOTE: The keyword 'PLACE_FLASH_HERE' is defined in r_flash.h and in conjunction with the
* FLASH_CFG_PARAM_CODE_FLASH_PROGRAMMING_ENABLE config setting, determines if sections of the Flash API will be copied
* to
* and executed from RAM. This is required for Data Flash BGO (Background) operation.
*/
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_irq_cfg (bool state, flash_cfg_t const * const p_cfg, IRQn_Type irq) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void HW_FLASH_LP_init (flash_lp_instance_ctrl_t * const p_ctrl, current_parameters_t * p_current_parameters) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_pe_mode_enter (flash_lp_instance_ctrl_t * const p_ctrl, flash_type_t flash_type) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_pe_mode_exit (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_erase (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t block_address, uint32_t num_blocks, uint32_t block_size) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_write (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t const src_start_address,
uint32_t dest_start_address,
uint32_t num_bytes,
uint32_t min_program_size) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_LP_blankcheck (flash_lp_instance_ctrl_t * const p_ctrl, uint32_t start_address, uint32_t num_bytes,
flash_result_t * result) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void HW_FLASH_LP_reset (flash_lp_instance_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t HW_FLASH_HP_stop (void) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
void flash_ReleaseState (void) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
bool flash_get_block_info (uint32_t addr, flash_block_info_t * p_block_info) PLACE_IN_RAM_SECTION;
/** FRDY ISR is only used for DataFlash operations. For Code flash operations are blocking. Therefore ISR does
* not need to be located in RAM.
*/
void fcu_frdyi_isr (void);
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* HW_FLASH_LP_PRIVATE_H */

View File

@ -0,0 +1,50 @@
/***********************************************************************************************************************
* Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* This file is part of Renesas SynergyTM Software Package (SSP)
*
* The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors ("Renesas") and subject to statutory and contractual protections.
*
* This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
* Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
* or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
* MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
* "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
* CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
* CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
* included in this file may be subject to different terms.
**********************************************************************************************************************/
#ifndef R_FLASH_LP_PRIVATE_API_H
#define R_FLASH_LP_PRIVATE_API_H
/* Common macro for SSP header files. There is also a corresponding SSP_FOOTER macro at the end of this file. */
SSP_HEADER
/***********************************************************************************************************************
* Private Instance API Functions. DO NOT USE! Use functions through Interface API structure instead.
**********************************************************************************************************************/
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t R_FLASH_LP_Open(flash_ctrl_t * const p_ctrl, flash_cfg_t const * const p_cfg) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_Write(flash_ctrl_t * const p_ctrl, uint32_t const src_address, uint32_t flash_address, uint32_t const num_bytes) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_Read(flash_ctrl_t * const p_ctrl, uint8_t * p_dest_address, uint32_t const flash_address, uint32_t const num_bytes)PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_Erase(flash_ctrl_t * const p_ctrl, uint32_t const address, uint32_t const num_blocks) PLACE_IN_RAM_SECTION;
/*LDRA_INSPECTED 219 s - This is an allowed exception to LDRA standard 219 S "User name starts with underscore."*/
ssp_err_t R_FLASH_LP_BlankCheck(flash_ctrl_t * const p_ctrl, uint32_t const address, uint32_t num_bytes, flash_result_t *blank_check_result) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_Close(flash_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_StatusGet(flash_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_AccessWindowSet(flash_ctrl_t * const p_ctrl, uint32_t const start_addr, uint32_t const end_addr) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_AccessWindowClear(flash_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_IdCodeSet(flash_ctrl_t * const p_ctrl, uint8_t const * const p_id_code, flash_id_code_mode_t mode) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_Reset(flash_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_StartUpAreaSelect(flash_ctrl_t * const p_ctrl, flash_startup_area_swap_t swap_type, bool is_temporary) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_UpdateFlashClockFreq (flash_ctrl_t * const p_ctrl) PLACE_IN_RAM_SECTION;
ssp_err_t R_FLASH_LP_VersionGet (ssp_version_t * const p_version);
ssp_err_t R_FLASH_LP_InfoGet (flash_ctrl_t * const p_ctrl, flash_info_t * const p_info);
/* Common macro for SSP header files. There is also a corresponding SSP_HEADER macro at the top of this file. */
SSP_FOOTER
#endif /* R_FLASH_LP_PRIVATE_API_H */

View File

@ -174,6 +174,10 @@ Synergy Configuration
Module "Timer Driver on r_gpt"
Parameter Checking: Default (BSP)
Module "Flash Driver on r_flash_lp"
Parameter Checking: Default (BSP)
Code Flash Programming Enable: Disabled
HAL
Instance "g_elc ELC Driver on r_elc"
Name [Fixed]: g_elc
@ -264,4 +268,10 @@ Synergy Configuration
Callback: timer_1ms
Overflow Interrupt Priority: Priority 3 (lowest - not valid if using ThreadX)
Instance "g_flash0 Flash Driver on r_flash_lp"
Name: g_flash0
Data Flash Background Operation: Disabled
Callback: NULL
Flash Ready Interrupt Priority: Disabled
Messaging