Improve XEBEC controller support

This commit is contained in:
Michael McMaster 2019-03-02 15:08:12 +10:00
parent 13aa4b823c
commit efca14f6b5
8 changed files with 3978 additions and 2 deletions

View File

@ -214,4 +214,15 @@ void scsiWriteBuffer()
}
}
// XEBEC specific command. See
// http://www.bitsavers.org/pdf/westernDigital/WD100x/79-000004_WD1002-SHD_OEM_Manual_Aug1984.pdf
// Section 4.3.14
void scsiWriteSectorBuffer()
{
scsiDev.dataLen = scsiDev.target->liveCfg.bytesPerSector;
scsiDev.phase = DATA_OUT;
scsiDev.postDataOutHook = doWriteBuffer;
}

View File

@ -20,6 +20,7 @@
void scsiSendDiagnostic(void);
void scsiReceiveDiagnostic(void);
void scsiWriteBuffer(void);
void scsiWriteSectorBuffer(void);
void scsiReadBuffer(void);
#endif

View File

@ -472,6 +472,11 @@ static void process_Command()
{
scsiWriteBuffer();
}
else if (command == 0x0f &&
scsiDev.target->cfg->quirks == CONFIG_QUIRKS_XEBEC)
{
scsiWriteSectorBuffer();
}
else if (command == 0x3C)
{
scsiReadBuffer();
@ -586,7 +591,16 @@ static void scsiReset()
// in which case TERMPWR cannot be supplied, and reset will ALWAYS
// be true. Therefore, the sleep here must be slow to avoid slowing
// USB comms
CyDelay(1); // 1ms.
// Also, need to exit quickly for XEBEC controllers which may
// assert RST immediately before pulsing a SEL.
uint32_t rstTimerBegin = getTime_ms();
while (SCSI_ReadFilt(SCSI_Filt_RST))
{
if (elapsedTime_ms(rstTimerBegin) >= 1)
{
break;
}
}
}
static void enter_SelectionPhase()
@ -735,6 +749,13 @@ static void process_SelectionPhase()
{
break;
}
else if (elapsedTime_ms(selTimerBegin) >= 10 &&
scsiDev.target->cfg->quirks == CONFIG_QUIRKS_XEBEC)
{
// XEBEC hosts may not bother releasing SEL at all until
// just before the command ends.
break;
}
else if (elapsedTime_ms(selTimerBegin) >= 250)
{
SCSI_ClearPin(SCSI_Out_BSY);

View File

@ -457,7 +457,6 @@ void scsiPhyReset()
#ifdef SCSI_Out_ACK
SCSI_ClearPin(SCSI_Out_ACK);
#endif
SCSI_ClearPin(SCSI_Out_RST);
SCSI_ClearPin(SCSI_Out_SEL);
SCSI_ClearPin(SCSI_Out_REQ);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,556 @@
/*******************************************************************************
* \file cy_em_eeprom.h
* \version 2.0
*
* \brief
* This file provides the function prototypes and constants for the Emulated
* EEPROM middleware library.
*
********************************************************************************
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \mainpage Cypress Em_EEPROM Middleware Library
*
* The Emulated EEPROM provides an API that allows creating an emulated
* EEPROM in flash that has the ability to do wear leveling and restore
* corrupted data from a redundant copy. The Emulated EEPROM library is designed
* to be used with the Em_EEPROM component.
*
* The Cy_Em_EEPROM API is described in the following sections:
* - \ref group_em_eeprom_macros
* - \ref group_em_eeprom_data_structures
* - \ref group_em_eeprom_enums
* - \ref group_em_eeprom_functions
*
* <b>Features:</b>
* * EEPROM-Like Non-Volatile Storage
* * Easy to use Read and Write API
* * Optional Wear Leveling
* * Optional Redundant Data storage
*
* \section group_em_eeprom_configuration Configuration Considerations
*
* The Em_EEPROM operates on the top of the flash driver. The flash driver has
* some prerequisites for proper operation. Refer to the "Flash System
* Routine (Flash)" section of the PDL API Reference Manual.
*
* <b>Initializing Emulated EEPROM in User flash</b>
*
* To initialize an Emulated EEPROM in the User flash, the EEPROM storage should
* be declared by the user. For the proper operation, the EEPROM storage should
* be aligned to the size of the flash row. An example of the EEPROM storage
* declaration is below (applicable for GCC and MDK compilers):
*
* CY_ALIGN(CY_EM_EEPROM_FLASH_SIZEOF_ROW)
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* The same declaration for the IAR compiler:
*
* #pragma data_alignment = CY_EM_EEPROM_FLASH_SIZEOF_ROW
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* Note that the name "emEeprom" is shown for reference. Any other name can be
* used instead. Also, note that the Em_EEPROM_PHYSICAL_SIZE constant is
* generated by the PSoC Creator Em_EEPROM component and so it is instance name
* dependent and its prefix should be changed when the name of the component
* changes. If the The Cy_Em_EEPROM middleware library is used without the
* Em_EEPROM component, the user has to provide a proper size for the EEPROM
* storage instead of Em_EEPROM_PHYSICAL_SIZE. The size of the EEPROM storage
* can be calculated using the following equation:
*
* Physical size = EEPROM data size * 2 * wear leveling * (1 + redundant copy)
*
* where,
* "EEPROM data size" - the size of data the user wants to store in the
* EEPROM. The data size must divide evenly to the half of the flash row size.
* "wear leveling" - the wear leveling factor (1-10).
* "redundant copy" - "zero" if a redundant copy is not used, and "one"
* otherwise.
*
* The start address of the storage should be filled to the Emulated EEPROM
* configuration structure and then passed to the Cy_Em_EEPROM_Init().
* If the Em_EEPROM component is used, the config (Em_EEPROM_config) and
* context structures (Em_EEPROM_context) are defined by the component, so the
* user may just use that structures otherwise both of the structures need to
* be provided by the user. Note that if the "Config Data in Flash"
* option is selected in the component, then the configuration structure should
* be copied to RAM to allow EEPROM storage start address update. The following
* code demonstrates utilization of "Em_EEPROM_config" and "Em_EEPROM_context"
* Em_EEPROM component structures for Cy_Em_EEPROM middleware library
* initialization:
*
* cy_en_em_eeprom_status_t retValue;
* cy_stc_eeprom_config_t config;
*
* memcpy((void *)&config,
(void *)&Em_EEPROM_config,
sizeof(cy_stc_eeprom_config_t));
* config.userFlashStartAddr = (uint32)emEeprom;
* retValue = Cy_Em_EEPROM_Init(&config, &Em_EEPROM_context);
*
* <b>Initializing EEPROM in Emulated EEPROM flash area</b>
*
* Initializing of the EEPROM storage in the Emulated EEPROM flash area is
* identical to initializing of the EEPROM storage in the User flash with one
* difference. The location of the Emulated EEPROM storage should be specified
* somewhere in the EmulatedEEPROM flash area. If the Em_EEPROM component is
* utilized in the project, then the respective storage
* (Em_EEPROM_em_EepromStorage[]) is automatically declared by the component
* if the "Use Emulated EEPROM" option is set to "Yes". The user just needs to
* fill the start address of the storage to the config structure. If the
* Em_EEPROM component is not used, the user needs to declare the storage
* in the Emulated EEPROM flash area. An example of such declaration is
* following (applicable for GCC and MDK compilers):
*
* CY_SECTION(".cy_em_eeprom") CY_ALIGN(CY_EM_EEPROM_FLASH_SIZEOF_ROW)
* const uint8_t emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* The same declaration for the IAR compiler:
*
* #pragma location = ".cy_em_eeprom"
* #pragma data_alignment = CY_EM_EEPROM_FLASH_SIZEOF_ROW
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* where,
* Em_EEPROM_PHYSICAL_SIZE - is a constant that is generated by the Em_EEPROM
* component when the component is utilized in the project or it should be
* provided by the user. The equation for the calculation of the constant is
* shown above.
*
* Note that the size of the Emulated EEPROM flash area is limited. Refer to the
* specific device datasheet for the value of the available EEPROM Emulation
* area.
*
* \section group_em_eeprom_more_information More Information
* See the Em_EEPROM Component datasheet.
*
*
* \section group_em_eeprom_MISRA MISRA-C Compliance
*
* The Cy_Em_EEPROM library has the following specific deviations:
*
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>The cast should not be performed between a pointer to the object type
* and a different pointer to the object type.</td>
* <td>The cast from the object type and a different pointer to the object
* was used intentionally because of the performance reasons.</td>
* </tr>
* <tr>
* <td>14.2</td>
* <td>R</td>
* <td>All non-null statements shall either have at least one side-effect,
* however executed, or cause control flow to change.</td>
* <td>To maintain common codebase, some variables, unused for a specific
* device, are casted to void to prevent generation of an unused variable
* compiler warning.</td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>A</td>
* <td>The object addressed by the pointer parameter is not modified and so
* the pointer could be of type 'pointer to const'.</td>
* <td>The warning is generated because of the pointer dereferencing to
* address which makes the MISRA checker think the data is not
* modified.</td>
* </tr>
* <tr>
* <td>17.4</td>
* <td>R</td>
* <td>The array indexing shall be the only allowed form of pointer
* arithmetic.</td>
* <td>The pointer arithmetic used in several places on the Cy_Em_EEPROM
* implementation is safe and preferred because it increases the code
* flexibility.</td>
* </tr>
* <tr>
* <td>19.7</td>
* <td>A</td>
* <td>A function shall be used in preference to a function-like macro.</td>
* <td>Macro is used because of performance reasons.</td>
* </tr>
* </table>
*
* \section group_em_eeprom_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial Version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_em_eeprom_macros Macros
* \brief
* This section describes the Emulated EEPROM Macros.
*
* \defgroup group_em_eeprom_functions Functions
* \brief
* This section describes the Emulated EEPROM Function Prototypes.
*
* \defgroup group_em_eeprom_data_structures Data Structures
* \brief
* Describes the data structures defined by the Emulated EEPROM.
*
* \defgroup group_em_eeprom_enums Enumerated types
* \brief
* Describes the enumeration types defined by the Emulated EEPROM.
*
*/
#if !defined(CY_EM_EEPROM_H)
#define CY_EM_EEPROM_H
#include "cytypes.h"
#include <stddef.h>
#if (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6)
#include <cy_device_headers.h>
#include "syslib/cy_syslib.h"
#include "flash/cy_flash.h"
#else
#include "CyFlash.h"
#include <cyfitter.h>
#endif /* (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6) */
/* The C binding of definitions if building with the C++ compiler */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***************************************
* Conditional Compilation Parameters
***************************************/
#define CY_PSOC6 (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6)
/***************************************
* Data Structure definitions
***************************************/
/**
* \addtogroup group_em_eeprom_data_structures
* \{
*/
/** EEPROM configuration structure */
typedef struct
{
/** The number of bytes to store in EEPROM */
uint32 eepromSize;
/** The amount of wear leveling from 1 to 10. 1 means no wear leveling
* is used.
*/
uint32 wearLevelingFactor;
/** If not zero, a redundant copy of the Em_EEPROM is included. */
uint8 redundantCopy;
/** If not zero, a blocking write to flash is used. Otherwise non-blocking
* write is used. This parameter is used only for PSoC 6.
*/
uint8 blockingWrite;
/** The start address for the EEPROM memory in the user's flash. */
uint32 userFlashStartAddr;
} cy_stc_eeprom_config_t;
/** \} group_em_eeprom_data_structures */
/** The EEPROM context data structure. It is used to store the specific
* EEPROM context data.
*/
typedef struct
{
/** The pointer to the end address of EEPROM including wear leveling overhead
* and excluding redundant copy overhead.
*/
uint32 wlEndAddr;
/** The number of flash rows allocated for the EEPROM excluding the number of
* rows allocated for wear leveling and redundant copy overhead.
*/
uint32 numberOfRows;
/** The address of the last written EEPROM row */
uint32 lastWrRowAddr;
/** The number of bytes to store in EEPROM */
uint32 eepromSize;
/** The amount of wear leveling from 1 to 10. 1 means no wear leveling
* is used.
*/
uint32 wearLevelingFactor;
/** If not zero, a redundant copy of the Em_EEPROM is included. */
uint8 redundantCopy;
/** If not zero, a blocking write to flash is used. Otherwise non-blocking
* write is used. This parameter is used only for PSoC 6.
*/
uint8 blockingWrite;
/** The start address for the EEPROM memory in the user's flash. */
uint32 userFlashStartAddr;
} cy_stc_eeprom_context_t;
#if (CY_PSOC6)
#define CY_EM_EEPROM_ID (CY_PDL_DRV_ID(0x1BuL)) /**< Em_EEPROM PDL ID */
/**
* \addtogroup group_em_eeprom_enums
* \{
* Specifies return values meaning.
*/
/** A prefix for EEPROM function error return-values */
#define CY_EM_EEPROM_ID_ERROR (uint32_t)(CY_EM_EEPROM_ID | CY_PDL_STATUS_ERROR)
#else
/** A prefix for EEPROM function status codes. For non-PSoC6 devices,
* prefix is zero.
*/
#define CY_EM_EEPROM_ID_ERROR (0uL)
#endif /* (CY_PSOC6) */
/***************************************
* Enumerated Types and Parameters
***************************************/
/** EEPROM return enumeration type */
typedef enum
{
CY_EM_EEPROM_SUCCESS = 0x00uL, /**< The function executed successfully */
CY_EM_EEPROM_BAD_PARAM = (CY_EM_EEPROM_ID_ERROR + 1uL), /**< The input parameter is invalid */
CY_EM_EEPROM_BAD_CHECKSUM = (CY_EM_EEPROM_ID_ERROR + 2uL), /**< The data in EEPROM is corrupted */
CY_EM_EEPROM_BAD_DATA = (CY_EM_EEPROM_ID_ERROR + 3uL), /**< Failed to place the EEPROM in flash */
CY_EM_EEPROM_WRITE_FAIL = (CY_EM_EEPROM_ID_ERROR + 4uL) /**< Write to EEPROM failed */
} cy_en_em_eeprom_status_t;
/** \} group_em_eeprom_enums */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_em_eeprom_functions
* \{
*/
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Init(cy_stc_eeprom_config_t* config, cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Read(uint32 addr,
void * eepromData,
uint32 size,
cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Write(uint32 addr,
void * eepromData,
uint32 size,
cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Erase(cy_stc_eeprom_context_t * context);
uint32 Cy_Em_EEPROM_NumWrites(cy_stc_eeprom_context_t * context);
/** \} group_em_eeprom_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_em_eeprom_macros
* \{
*/
/** Library major version */
#define CY_EM_EEPROM_VERSION_MAJOR (2)
/** Library minor version */
#define CY_EM_EEPROM_VERSION_MINOR (0)
/** Defines the maximum data length that can be stored in one flash row */
#define CY_EM_EEPROM_EEPROM_DATA_LEN (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)
/** \} group_em_eeprom_macros */
/***************************************
* Macro definitions
***************************************/
/** \cond INTERNAL */
/* Defines the size of flash row */
#define CY_EM_EEPROM_FLASH_SIZEOF_ROW (CY_FLASH_SIZEOF_ROW)
/* Device specific flash constants */
#if (!CY_PSOC6)
#define CY_EM_EEPROM_FLASH_BASE_ADDR (CYDEV_FLASH_BASE)
#define CY_EM_EEPROM_FLASH_SIZE (CYDEV_FLASH_SIZE)
#define CY_EM_EEPROM_ROWS_IN_ARRAY (CY_FLASH_SIZEOF_ARRAY / CY_EM_EEPROM_FLASH_SIZEOF_ROW)
#if (CY_PSOC3)
#define CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX (0xff0000uL)
#define CY_EM_EEPROM_CODE_ADDR_END \
(CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX + (CY_EM_EEPROM_FLASH_SIZE - 1u))
#define CY_EM_EEPROM_CODE_ADDR_MASK (0xffffu)
/* Checks if the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((startAddr) > CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX) && \
((endAddr) <= CY_EM_EEPROM_CODE_ADDR_END))
#else
/* Checks is the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((startAddr) > CY_EM_EEPROM_FLASH_BASE_ADDR) && ((endAddr) <= CY_EM_EEPROM_FLASH_END_ADDR))
#endif /* (CY_PSOC3) */
#else
#define CY_EM_EEPROM_FLASH_BASE_ADDR (CY_FLASH_BASE)
#define CY_EM_EEPROM_FLASH_SIZE (CY_FLASH_SIZE)
#define CY_EM_EEPROM_EM_EEPROM_BASE_ADDR (CY_EM_EEPROM_BASE)
#define CY_EM_EEPROM_EM_EEPROM_SIZE (CY_EM_EEPROM_SIZE)
#define CY_EM_EEPROM_EM_EEPROM_END_ADDR (CY_EM_EEPROM_EM_EEPROM_BASE_ADDR + CY_EM_EEPROM_EM_EEPROM_SIZE)
/* Checks is the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((((startAddr) > CY_EM_EEPROM_FLASH_BASE_ADDR) && ((endAddr) <= CY_EM_EEPROM_FLASH_END_ADDR)) || \
(((startAddr) >= CY_EM_EEPROM_EM_EEPROM_BASE_ADDR) && \
((endAddr) <= CY_EM_EEPROM_EM_EEPROM_END_ADDR))))
#endif /* (!CY_PSOC6) */
#define CY_EM_EEPROM_FLASH_END_ADDR (CY_EM_EEPROM_FLASH_BASE_ADDR + CY_EM_EEPROM_FLASH_SIZE)
/* Defines the length of EEPROM data that can be stored in Em_EEPROM header */
#define CY_EM_EEPROM_HEADER_DATA_LEN ((CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u) - 16u)
#define CY_EM_EEPROM_ADDR_IN_RANGE (1u)
/* Return CY_EM_EEPROM_ADDR_IN_RANGE if addr exceeded the upper range of
* EEPROM. The wear leveling overhead is included in the range but redundant copy
* is excluded.
*/
#define CY_EM_EEPROM_IS_ADDR_EXCEED_RANGE(addr, endEepromAddr) \
(((addr) >= (endEepromAddr)) ? (0u) : (CY_EM_EEPROM_ADDR_IN_RANGE))
/* Check to see if the specified address is present in the EEPROM */
#define CY_EM_EEPROM_IS_ADDR_IN_RANGE(addr, startEepromAddr, endEepromAddr) \
(((addr) > (startEepromAddr)) ? \
(((addr) < (endEepromAddr)) ? (CY_EM_EEPROM_ADDR_IN_RANGE) : (0u)) : (0u))
/* Check if the EEPROM address locations from startAddr1 to endAddr1
* are crossed with EEPROM address locations from startAddr2 to endAddr2.
*/
#define CY_EM_EEPROM_IS_ADDRESES_CROSSING(startAddr1, endAddr1 , startAddr2, endAddr2) \
(((startAddr1) > (startAddr2)) ? (((startAddr1) >= (endAddr2)) ? (0u) : (1u) ) : \
(((startAddr2) >= (endAddr1)) ? (0u) : (1u)))
/* Return the pointer to the start of the redundant copy of the EEPROM */
#define CY_EM_EEPROM_GET_REDNT_COPY_ADDR_BASE(numRows, wearLeveling, eepromStartAddr) \
((((numRows) * CY_EM_EEPROM_FLASH_SIZEOF_ROW) * (wearLeveling)) + (eepromStartAddr))
/* Return the number of the row in EM_EEPROM which contains an address defined by
* rowAddr.
*/
#define CY_EM_EEPROM_GET_ACT_ROW_NUM_FROM_ADDR(rowAddr, maxRows, eepromStartAddr) \
((((rowAddr) - (eepromStartAddr)) / CY_EM_EEPROM_FLASH_SIZEOF_ROW) % (maxRows))
/** Returns the size allocated for the EEPROM excluding wear leveling and
* redundant copy overhead.
*/
#define CY_EM_EEPROM_GET_EEPROM_SIZE(numRows) ((numRows) * CY_EM_EEPROM_FLASH_SIZEOF_ROW)
/* Check if the given address belongs to the EEPROM address of the row
* specified by rowNum.
*/
#define CY_EM_EEPROM_IS_ADDR_IN_ROW_RANGE(addr, rowNum) \
(((addr) < ((rowNum) * (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u))) ? (0u) : \
(((addr) > ((((rowNum) + 1u) * (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)) - 1u)) ? \
(0u) : (1u)))
/* CRC-8 constants */
#define CY_EM_EEPROM_CRC8_POLYNOM ((uint8)(0x31u))
#define CY_EM_EEPROM_CRC8_POLYNOM_LEN (8u)
#define CY_EM_EEPROM_CRC8_SEED (0xFFu)
#define CY_EM_EEPROM_CRC8_XOR_VAL ((uint8) (0x80u))
#define CY_EM_EEPROM_CALCULATE_CRC8(crc) \
((CY_EM_EEPROM_CRC8_XOR_VAL == ((crc) & CY_EM_EEPROM_CRC8_XOR_VAL)) ? \
((uint8)(((uint8)((uint8)((crc) << 1u))) ^ CY_EM_EEPROM_CRC8_POLYNOM)) : ((uint8)((crc) << 1u)))
#define CY_EM_EEPROM_GET_SEQ_NUM(addr) (*(uint32*)(addr))
/** \endcond */
/**
* \addtogroup group_em_eeprom_macros
* \{
*/
/** Calculate the number of flash rows required to create an Em_EEPROM of
* dataSize.
*/
#define CY_EM_EEPROM_GET_NUM_ROWS_IN_EEPROM(dataSize) \
(((dataSize) / (CY_EM_EEPROM_EEPROM_DATA_LEN)) + \
((((dataSize) % (CY_EM_EEPROM_EEPROM_DATA_LEN)) != 0u) ? 1U : 0U))
/** Returns the size of flash allocated for EEPROM including wear leveling and
* redundant copy overhead.
*/
#define CY_EM_EEPROM_GET_PHYSICAL_SIZE(dataSize, wearLeveling, redundantCopy) \
(((CY_EM_EEPROM_GET_NUM_ROWS_IN_EEPROM(dataSize) * \
CY_EM_EEPROM_FLASH_SIZEOF_ROW) * \
(wearLeveling)) * (1uL + (redundantCopy)))
/** \} group_em_eeprom_macros */
/******************************************************************************
* Local definitions
*******************************************************************************/
/** \cond INTERNAL */
/* Offsets for 32-bit RAM buffer addressing */
#define CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32 ((CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u) / 4u)
#define CY_EM_EEPROM_HEADER_SEQ_NUM_OFFSET_U32 (0u)
#define CY_EM_EEPROM_HEADER_ADDR_OFFSET_U32 (1u)
#define CY_EM_EEPROM_HEADER_LEN_OFFSET_U32 (2u)
#define CY_EM_EEPROM_HEADER_DATA_OFFSET_U32 (3u)
#define CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32 (CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32 - 1u)
/* The same offsets as above used for direct memory addressing */
#define CY_EM_EEPROM_EEPROM_DATA_OFFSET (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)
#define CY_EM_EEPROM_HEADER_ADDR_OFFSET (4u)
#define CY_EM_EEPROM_HEADER_LEN_OFFSET (8u)
#define CY_EM_EEPROM_HEADER_DATA_OFFSET (12u)
#define CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET (CY_EM_EEPROM_EEPROM_DATA_OFFSET - 4u)
#define CY_EM_EEPROM_U32_DIV (4u)
/* Maximum wear leveling value */
#define CY_EM_EEPROM_MAX_WEAR_LEVELING_FACTOR (10u)
/* Maximum allowed flash row write/erase operation duration */
#define CY_EM_EEPROM_MAX_WRITE_DURATION_MS (50u)
/** \endcond */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CY_EM_EEPROM_H */
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,556 @@
/*******************************************************************************
* \file cy_em_eeprom.h
* \version 2.0
*
* \brief
* This file provides the function prototypes and constants for the Emulated
* EEPROM middleware library.
*
********************************************************************************
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \mainpage Cypress Em_EEPROM Middleware Library
*
* The Emulated EEPROM provides an API that allows creating an emulated
* EEPROM in flash that has the ability to do wear leveling and restore
* corrupted data from a redundant copy. The Emulated EEPROM library is designed
* to be used with the Em_EEPROM component.
*
* The Cy_Em_EEPROM API is described in the following sections:
* - \ref group_em_eeprom_macros
* - \ref group_em_eeprom_data_structures
* - \ref group_em_eeprom_enums
* - \ref group_em_eeprom_functions
*
* <b>Features:</b>
* * EEPROM-Like Non-Volatile Storage
* * Easy to use Read and Write API
* * Optional Wear Leveling
* * Optional Redundant Data storage
*
* \section group_em_eeprom_configuration Configuration Considerations
*
* The Em_EEPROM operates on the top of the flash driver. The flash driver has
* some prerequisites for proper operation. Refer to the "Flash System
* Routine (Flash)" section of the PDL API Reference Manual.
*
* <b>Initializing Emulated EEPROM in User flash</b>
*
* To initialize an Emulated EEPROM in the User flash, the EEPROM storage should
* be declared by the user. For the proper operation, the EEPROM storage should
* be aligned to the size of the flash row. An example of the EEPROM storage
* declaration is below (applicable for GCC and MDK compilers):
*
* CY_ALIGN(CY_EM_EEPROM_FLASH_SIZEOF_ROW)
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* The same declaration for the IAR compiler:
*
* #pragma data_alignment = CY_EM_EEPROM_FLASH_SIZEOF_ROW
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* Note that the name "emEeprom" is shown for reference. Any other name can be
* used instead. Also, note that the Em_EEPROM_PHYSICAL_SIZE constant is
* generated by the PSoC Creator Em_EEPROM component and so it is instance name
* dependent and its prefix should be changed when the name of the component
* changes. If the The Cy_Em_EEPROM middleware library is used without the
* Em_EEPROM component, the user has to provide a proper size for the EEPROM
* storage instead of Em_EEPROM_PHYSICAL_SIZE. The size of the EEPROM storage
* can be calculated using the following equation:
*
* Physical size = EEPROM data size * 2 * wear leveling * (1 + redundant copy)
*
* where,
* "EEPROM data size" - the size of data the user wants to store in the
* EEPROM. The data size must divide evenly to the half of the flash row size.
* "wear leveling" - the wear leveling factor (1-10).
* "redundant copy" - "zero" if a redundant copy is not used, and "one"
* otherwise.
*
* The start address of the storage should be filled to the Emulated EEPROM
* configuration structure and then passed to the Cy_Em_EEPROM_Init().
* If the Em_EEPROM component is used, the config (Em_EEPROM_config) and
* context structures (Em_EEPROM_context) are defined by the component, so the
* user may just use that structures otherwise both of the structures need to
* be provided by the user. Note that if the "Config Data in Flash"
* option is selected in the component, then the configuration structure should
* be copied to RAM to allow EEPROM storage start address update. The following
* code demonstrates utilization of "Em_EEPROM_config" and "Em_EEPROM_context"
* Em_EEPROM component structures for Cy_Em_EEPROM middleware library
* initialization:
*
* cy_en_em_eeprom_status_t retValue;
* cy_stc_eeprom_config_t config;
*
* memcpy((void *)&config,
(void *)&Em_EEPROM_config,
sizeof(cy_stc_eeprom_config_t));
* config.userFlashStartAddr = (uint32)emEeprom;
* retValue = Cy_Em_EEPROM_Init(&config, &Em_EEPROM_context);
*
* <b>Initializing EEPROM in Emulated EEPROM flash area</b>
*
* Initializing of the EEPROM storage in the Emulated EEPROM flash area is
* identical to initializing of the EEPROM storage in the User flash with one
* difference. The location of the Emulated EEPROM storage should be specified
* somewhere in the EmulatedEEPROM flash area. If the Em_EEPROM component is
* utilized in the project, then the respective storage
* (Em_EEPROM_em_EepromStorage[]) is automatically declared by the component
* if the "Use Emulated EEPROM" option is set to "Yes". The user just needs to
* fill the start address of the storage to the config structure. If the
* Em_EEPROM component is not used, the user needs to declare the storage
* in the Emulated EEPROM flash area. An example of such declaration is
* following (applicable for GCC and MDK compilers):
*
* CY_SECTION(".cy_em_eeprom") CY_ALIGN(CY_EM_EEPROM_FLASH_SIZEOF_ROW)
* const uint8_t emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* The same declaration for the IAR compiler:
*
* #pragma location = ".cy_em_eeprom"
* #pragma data_alignment = CY_EM_EEPROM_FLASH_SIZEOF_ROW
* const uint8 emEeprom[Em_EEPROM_PHYSICAL_SIZE] = {0u};
*
* where,
* Em_EEPROM_PHYSICAL_SIZE - is a constant that is generated by the Em_EEPROM
* component when the component is utilized in the project or it should be
* provided by the user. The equation for the calculation of the constant is
* shown above.
*
* Note that the size of the Emulated EEPROM flash area is limited. Refer to the
* specific device datasheet for the value of the available EEPROM Emulation
* area.
*
* \section group_em_eeprom_more_information More Information
* See the Em_EEPROM Component datasheet.
*
*
* \section group_em_eeprom_MISRA MISRA-C Compliance
*
* The Cy_Em_EEPROM library has the following specific deviations:
*
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>The cast should not be performed between a pointer to the object type
* and a different pointer to the object type.</td>
* <td>The cast from the object type and a different pointer to the object
* was used intentionally because of the performance reasons.</td>
* </tr>
* <tr>
* <td>14.2</td>
* <td>R</td>
* <td>All non-null statements shall either have at least one side-effect,
* however executed, or cause control flow to change.</td>
* <td>To maintain common codebase, some variables, unused for a specific
* device, are casted to void to prevent generation of an unused variable
* compiler warning.</td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>A</td>
* <td>The object addressed by the pointer parameter is not modified and so
* the pointer could be of type 'pointer to const'.</td>
* <td>The warning is generated because of the pointer dereferencing to
* address which makes the MISRA checker think the data is not
* modified.</td>
* </tr>
* <tr>
* <td>17.4</td>
* <td>R</td>
* <td>The array indexing shall be the only allowed form of pointer
* arithmetic.</td>
* <td>The pointer arithmetic used in several places on the Cy_Em_EEPROM
* implementation is safe and preferred because it increases the code
* flexibility.</td>
* </tr>
* <tr>
* <td>19.7</td>
* <td>A</td>
* <td>A function shall be used in preference to a function-like macro.</td>
* <td>Macro is used because of performance reasons.</td>
* </tr>
* </table>
*
* \section group_em_eeprom_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial Version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_em_eeprom_macros Macros
* \brief
* This section describes the Emulated EEPROM Macros.
*
* \defgroup group_em_eeprom_functions Functions
* \brief
* This section describes the Emulated EEPROM Function Prototypes.
*
* \defgroup group_em_eeprom_data_structures Data Structures
* \brief
* Describes the data structures defined by the Emulated EEPROM.
*
* \defgroup group_em_eeprom_enums Enumerated types
* \brief
* Describes the enumeration types defined by the Emulated EEPROM.
*
*/
#if !defined(CY_EM_EEPROM_H)
#define CY_EM_EEPROM_H
#include "cytypes.h"
#include <stddef.h>
#if (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6)
#include <cy_device_headers.h>
#include "syslib/cy_syslib.h"
#include "flash/cy_flash.h"
#else
#include "CyFlash.h"
#include <cyfitter.h>
#endif /* (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6) */
/* The C binding of definitions if building with the C++ compiler */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***************************************
* Conditional Compilation Parameters
***************************************/
#define CY_PSOC6 (CYDEV_CHIP_FAMILY_USED == CYDEV_CHIP_FAMILY_PSOC6)
/***************************************
* Data Structure definitions
***************************************/
/**
* \addtogroup group_em_eeprom_data_structures
* \{
*/
/** EEPROM configuration structure */
typedef struct
{
/** The number of bytes to store in EEPROM */
uint32 eepromSize;
/** The amount of wear leveling from 1 to 10. 1 means no wear leveling
* is used.
*/
uint32 wearLevelingFactor;
/** If not zero, a redundant copy of the Em_EEPROM is included. */
uint8 redundantCopy;
/** If not zero, a blocking write to flash is used. Otherwise non-blocking
* write is used. This parameter is used only for PSoC 6.
*/
uint8 blockingWrite;
/** The start address for the EEPROM memory in the user's flash. */
uint32 userFlashStartAddr;
} cy_stc_eeprom_config_t;
/** \} group_em_eeprom_data_structures */
/** The EEPROM context data structure. It is used to store the specific
* EEPROM context data.
*/
typedef struct
{
/** The pointer to the end address of EEPROM including wear leveling overhead
* and excluding redundant copy overhead.
*/
uint32 wlEndAddr;
/** The number of flash rows allocated for the EEPROM excluding the number of
* rows allocated for wear leveling and redundant copy overhead.
*/
uint32 numberOfRows;
/** The address of the last written EEPROM row */
uint32 lastWrRowAddr;
/** The number of bytes to store in EEPROM */
uint32 eepromSize;
/** The amount of wear leveling from 1 to 10. 1 means no wear leveling
* is used.
*/
uint32 wearLevelingFactor;
/** If not zero, a redundant copy of the Em_EEPROM is included. */
uint8 redundantCopy;
/** If not zero, a blocking write to flash is used. Otherwise non-blocking
* write is used. This parameter is used only for PSoC 6.
*/
uint8 blockingWrite;
/** The start address for the EEPROM memory in the user's flash. */
uint32 userFlashStartAddr;
} cy_stc_eeprom_context_t;
#if (CY_PSOC6)
#define CY_EM_EEPROM_ID (CY_PDL_DRV_ID(0x1BuL)) /**< Em_EEPROM PDL ID */
/**
* \addtogroup group_em_eeprom_enums
* \{
* Specifies return values meaning.
*/
/** A prefix for EEPROM function error return-values */
#define CY_EM_EEPROM_ID_ERROR (uint32_t)(CY_EM_EEPROM_ID | CY_PDL_STATUS_ERROR)
#else
/** A prefix for EEPROM function status codes. For non-PSoC6 devices,
* prefix is zero.
*/
#define CY_EM_EEPROM_ID_ERROR (0uL)
#endif /* (CY_PSOC6) */
/***************************************
* Enumerated Types and Parameters
***************************************/
/** EEPROM return enumeration type */
typedef enum
{
CY_EM_EEPROM_SUCCESS = 0x00uL, /**< The function executed successfully */
CY_EM_EEPROM_BAD_PARAM = (CY_EM_EEPROM_ID_ERROR + 1uL), /**< The input parameter is invalid */
CY_EM_EEPROM_BAD_CHECKSUM = (CY_EM_EEPROM_ID_ERROR + 2uL), /**< The data in EEPROM is corrupted */
CY_EM_EEPROM_BAD_DATA = (CY_EM_EEPROM_ID_ERROR + 3uL), /**< Failed to place the EEPROM in flash */
CY_EM_EEPROM_WRITE_FAIL = (CY_EM_EEPROM_ID_ERROR + 4uL) /**< Write to EEPROM failed */
} cy_en_em_eeprom_status_t;
/** \} group_em_eeprom_enums */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_em_eeprom_functions
* \{
*/
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Init(cy_stc_eeprom_config_t* config, cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Read(uint32 addr,
void * eepromData,
uint32 size,
cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Write(uint32 addr,
void * eepromData,
uint32 size,
cy_stc_eeprom_context_t * context);
cy_en_em_eeprom_status_t Cy_Em_EEPROM_Erase(cy_stc_eeprom_context_t * context);
uint32 Cy_Em_EEPROM_NumWrites(cy_stc_eeprom_context_t * context);
/** \} group_em_eeprom_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_em_eeprom_macros
* \{
*/
/** Library major version */
#define CY_EM_EEPROM_VERSION_MAJOR (2)
/** Library minor version */
#define CY_EM_EEPROM_VERSION_MINOR (0)
/** Defines the maximum data length that can be stored in one flash row */
#define CY_EM_EEPROM_EEPROM_DATA_LEN (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)
/** \} group_em_eeprom_macros */
/***************************************
* Macro definitions
***************************************/
/** \cond INTERNAL */
/* Defines the size of flash row */
#define CY_EM_EEPROM_FLASH_SIZEOF_ROW (CY_FLASH_SIZEOF_ROW)
/* Device specific flash constants */
#if (!CY_PSOC6)
#define CY_EM_EEPROM_FLASH_BASE_ADDR (CYDEV_FLASH_BASE)
#define CY_EM_EEPROM_FLASH_SIZE (CYDEV_FLASH_SIZE)
#define CY_EM_EEPROM_ROWS_IN_ARRAY (CY_FLASH_SIZEOF_ARRAY / CY_EM_EEPROM_FLASH_SIZEOF_ROW)
#if (CY_PSOC3)
#define CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX (0xff0000uL)
#define CY_EM_EEPROM_CODE_ADDR_END \
(CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX + (CY_EM_EEPROM_FLASH_SIZE - 1u))
#define CY_EM_EEPROM_CODE_ADDR_MASK (0xffffu)
/* Checks if the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((startAddr) > CY_EM_EEPROM_CODE_MEM_CLASS_PREFIX) && \
((endAddr) <= CY_EM_EEPROM_CODE_ADDR_END))
#else
/* Checks is the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((startAddr) > CY_EM_EEPROM_FLASH_BASE_ADDR) && ((endAddr) <= CY_EM_EEPROM_FLASH_END_ADDR))
#endif /* (CY_PSOC3) */
#else
#define CY_EM_EEPROM_FLASH_BASE_ADDR (CY_FLASH_BASE)
#define CY_EM_EEPROM_FLASH_SIZE (CY_FLASH_SIZE)
#define CY_EM_EEPROM_EM_EEPROM_BASE_ADDR (CY_EM_EEPROM_BASE)
#define CY_EM_EEPROM_EM_EEPROM_SIZE (CY_EM_EEPROM_SIZE)
#define CY_EM_EEPROM_EM_EEPROM_END_ADDR (CY_EM_EEPROM_EM_EEPROM_BASE_ADDR + CY_EM_EEPROM_EM_EEPROM_SIZE)
/* Checks is the EEPROM is in flash range */
#define CY_EM_EEPROM_IS_IN_FLASH_RANGE(startAddr, endAddr) \
(((((startAddr) > CY_EM_EEPROM_FLASH_BASE_ADDR) && ((endAddr) <= CY_EM_EEPROM_FLASH_END_ADDR)) || \
(((startAddr) >= CY_EM_EEPROM_EM_EEPROM_BASE_ADDR) && \
((endAddr) <= CY_EM_EEPROM_EM_EEPROM_END_ADDR))))
#endif /* (!CY_PSOC6) */
#define CY_EM_EEPROM_FLASH_END_ADDR (CY_EM_EEPROM_FLASH_BASE_ADDR + CY_EM_EEPROM_FLASH_SIZE)
/* Defines the length of EEPROM data that can be stored in Em_EEPROM header */
#define CY_EM_EEPROM_HEADER_DATA_LEN ((CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u) - 16u)
#define CY_EM_EEPROM_ADDR_IN_RANGE (1u)
/* Return CY_EM_EEPROM_ADDR_IN_RANGE if addr exceeded the upper range of
* EEPROM. The wear leveling overhead is included in the range but redundant copy
* is excluded.
*/
#define CY_EM_EEPROM_IS_ADDR_EXCEED_RANGE(addr, endEepromAddr) \
(((addr) >= (endEepromAddr)) ? (0u) : (CY_EM_EEPROM_ADDR_IN_RANGE))
/* Check to see if the specified address is present in the EEPROM */
#define CY_EM_EEPROM_IS_ADDR_IN_RANGE(addr, startEepromAddr, endEepromAddr) \
(((addr) > (startEepromAddr)) ? \
(((addr) < (endEepromAddr)) ? (CY_EM_EEPROM_ADDR_IN_RANGE) : (0u)) : (0u))
/* Check if the EEPROM address locations from startAddr1 to endAddr1
* are crossed with EEPROM address locations from startAddr2 to endAddr2.
*/
#define CY_EM_EEPROM_IS_ADDRESES_CROSSING(startAddr1, endAddr1 , startAddr2, endAddr2) \
(((startAddr1) > (startAddr2)) ? (((startAddr1) >= (endAddr2)) ? (0u) : (1u) ) : \
(((startAddr2) >= (endAddr1)) ? (0u) : (1u)))
/* Return the pointer to the start of the redundant copy of the EEPROM */
#define CY_EM_EEPROM_GET_REDNT_COPY_ADDR_BASE(numRows, wearLeveling, eepromStartAddr) \
((((numRows) * CY_EM_EEPROM_FLASH_SIZEOF_ROW) * (wearLeveling)) + (eepromStartAddr))
/* Return the number of the row in EM_EEPROM which contains an address defined by
* rowAddr.
*/
#define CY_EM_EEPROM_GET_ACT_ROW_NUM_FROM_ADDR(rowAddr, maxRows, eepromStartAddr) \
((((rowAddr) - (eepromStartAddr)) / CY_EM_EEPROM_FLASH_SIZEOF_ROW) % (maxRows))
/** Returns the size allocated for the EEPROM excluding wear leveling and
* redundant copy overhead.
*/
#define CY_EM_EEPROM_GET_EEPROM_SIZE(numRows) ((numRows) * CY_EM_EEPROM_FLASH_SIZEOF_ROW)
/* Check if the given address belongs to the EEPROM address of the row
* specified by rowNum.
*/
#define CY_EM_EEPROM_IS_ADDR_IN_ROW_RANGE(addr, rowNum) \
(((addr) < ((rowNum) * (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u))) ? (0u) : \
(((addr) > ((((rowNum) + 1u) * (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)) - 1u)) ? \
(0u) : (1u)))
/* CRC-8 constants */
#define CY_EM_EEPROM_CRC8_POLYNOM ((uint8)(0x31u))
#define CY_EM_EEPROM_CRC8_POLYNOM_LEN (8u)
#define CY_EM_EEPROM_CRC8_SEED (0xFFu)
#define CY_EM_EEPROM_CRC8_XOR_VAL ((uint8) (0x80u))
#define CY_EM_EEPROM_CALCULATE_CRC8(crc) \
((CY_EM_EEPROM_CRC8_XOR_VAL == ((crc) & CY_EM_EEPROM_CRC8_XOR_VAL)) ? \
((uint8)(((uint8)((uint8)((crc) << 1u))) ^ CY_EM_EEPROM_CRC8_POLYNOM)) : ((uint8)((crc) << 1u)))
#define CY_EM_EEPROM_GET_SEQ_NUM(addr) (*(uint32*)(addr))
/** \endcond */
/**
* \addtogroup group_em_eeprom_macros
* \{
*/
/** Calculate the number of flash rows required to create an Em_EEPROM of
* dataSize.
*/
#define CY_EM_EEPROM_GET_NUM_ROWS_IN_EEPROM(dataSize) \
(((dataSize) / (CY_EM_EEPROM_EEPROM_DATA_LEN)) + \
((((dataSize) % (CY_EM_EEPROM_EEPROM_DATA_LEN)) != 0u) ? 1U : 0U))
/** Returns the size of flash allocated for EEPROM including wear leveling and
* redundant copy overhead.
*/
#define CY_EM_EEPROM_GET_PHYSICAL_SIZE(dataSize, wearLeveling, redundantCopy) \
(((CY_EM_EEPROM_GET_NUM_ROWS_IN_EEPROM(dataSize) * \
CY_EM_EEPROM_FLASH_SIZEOF_ROW) * \
(wearLeveling)) * (1uL + (redundantCopy)))
/** \} group_em_eeprom_macros */
/******************************************************************************
* Local definitions
*******************************************************************************/
/** \cond INTERNAL */
/* Offsets for 32-bit RAM buffer addressing */
#define CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32 ((CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u) / 4u)
#define CY_EM_EEPROM_HEADER_SEQ_NUM_OFFSET_U32 (0u)
#define CY_EM_EEPROM_HEADER_ADDR_OFFSET_U32 (1u)
#define CY_EM_EEPROM_HEADER_LEN_OFFSET_U32 (2u)
#define CY_EM_EEPROM_HEADER_DATA_OFFSET_U32 (3u)
#define CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32 (CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32 - 1u)
/* The same offsets as above used for direct memory addressing */
#define CY_EM_EEPROM_EEPROM_DATA_OFFSET (CY_EM_EEPROM_FLASH_SIZEOF_ROW / 2u)
#define CY_EM_EEPROM_HEADER_ADDR_OFFSET (4u)
#define CY_EM_EEPROM_HEADER_LEN_OFFSET (8u)
#define CY_EM_EEPROM_HEADER_DATA_OFFSET (12u)
#define CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET (CY_EM_EEPROM_EEPROM_DATA_OFFSET - 4u)
#define CY_EM_EEPROM_U32_DIV (4u)
/* Maximum wear leveling value */
#define CY_EM_EEPROM_MAX_WEAR_LEVELING_FACTOR (10u)
/* Maximum allowed flash row write/erase operation duration */
#define CY_EM_EEPROM_MAX_WRITE_DURATION_MS (50u)
/** \endcond */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CY_EM_EEPROM_H */
/* [] END OF FILE */