Microchip® Advanced Software Framework

rww_eeprom.c File Reference

SAM Read While Write EEPROM Emulator.

Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.

#include "rww_eeprom.h"
#include <string.h>
#include <nvm.h>
#include "conf_rwwee.h"

Data Structures

struct  _rww_eeprom_master_page
 Structure describing the EEPROM Emulation master page. More...
 
struct  _rww_eeprom_module
 Internal device instance struct. More...
 
struct  _rww_eeprom_page
 Structure describing emulated pages of RWW EEPROM data. More...
 

Macros

#define CONF_LOGICAL_PAGE_NUM_IN_ROW   RWWEE_LOGICAL_PAGE_NUM_1
 Configuration option, one logical page stored in a physical row. More...
 
#define CONF_PAGE_CHECKSUM_ENABLE   false
 Configuration option, page checksum enabled. More...
 
#define RWW_EEPROM_MAGIC_KEY   {0x41744545, 0x50524f4d, 0x456d752d,0x5257572e}
 
#define RWW_EEPROM_MAGIC_KEY_COUNT   4
 
#define RWW_EEPROM_MAX_LOGICAL_PAGES
 

Functions

static void _rww_eeprom_emulator_check_logical_page (void)
 Check if there exist rows with same logical pages due to power drop when writing or erasing page. More...
 
static void _rww_eeprom_emulator_create_master_page (void)
 Create master emulated RWW EEPROM management page. More...
 
static void _rww_eeprom_emulator_erase_invalid_page (uint16_t pre_phy_page, uint16_t next_phy_page)
 Erase one invalid page according to two invalid physical page. More...
 
static void _rww_eeprom_emulator_format_memory (void)
 Initializes the emulated RWW EEPROM memory, destroying the current contents. More...
 
static bool _rww_eeprom_emulator_is_full_row (uint16_t phy_page)
 Check if a row is a full row because the page is a invalid page, so if two pages have data, it is the full row. More...
 
static bool _rww_eeprom_emulator_is_page_free_on_row (const uint8_t start_physical_page, uint8_t *const free_physical_page)
 Finds the next free page in the given row if one is available. More...
 
static enum status_code _rww_eeprom_emulator_move_data_to_spare (const uint8_t row_number, const uint8_t logical_page, const uint8_t *const data)
 Moves data from the specified logical page to the spare row. More...
 
static void _rww_eeprom_emulator_nvm_commit_cache (const uint16_t physical_page)
 Commits the internal NVM controller page buffer to physical memory. More...
 
static void _rww_eeprom_emulator_nvm_erase_row (const uint8_t row)
 Erases a given row within the physical RWW EEPROM memory space. More...
 
static void _rww_eeprom_emulator_nvm_fill_cache (const uint16_t physical_page, const void *const data)
 Fills the internal NVM controller page buffer in physical RWW EEPROM memory space. More...
 
static bool _rww_eeprom_emulator_nvm_read_page (const uint16_t physical_page, void *const data)
 Reads a page of data stored in physical RWW EEPROM memory space. More...
 
static uint8_t _rww_eeprom_emulator_page_checksum (const uint8_t *buffer)
 RWW EEPROM Page Checksum. More...
 
static void _rww_eeprom_emulator_update_page_mapping (void)
 Creates a map in SRAM to translate logical RWW EEPROM pages to physical pages. More...
 
static enum status_code _rww_eeprom_emulator_verify_master_page (void)
 Verify the contents of a master RWW EEPROM page. More...
 
 COMPILER_PACK_RESET ()
 
 COMPILER_PACK_SET (1)
 
enum status_code rww_eeprom_emulator_commit_page_buffer (void)
 Commits any cached data to physical non-volatile memory. More...
 
void rww_eeprom_emulator_erase_memory (void)
 Erases the entire emulated RWW EEPROM memory space. More...
 
enum status_code rww_eeprom_emulator_get_parameters (struct rww_eeprom_emulator_parameters *const parameters)
 Retrieves the parameters of the RWW EEPROM Emulator memory layout. More...
 
enum status_code rww_eeprom_emulator_init (void)
 Initializes the RWW EEPROM Emulator service. More...
 
enum status_code rww_eeprom_emulator_read_buffer (const uint16_t offset, uint8_t *const data, const uint16_t length)
 Reads a buffer of data from the emulated RWW EEPROM memory space. More...
 
enum status_code rww_eeprom_emulator_read_page (const uint8_t logical_page, uint8_t *const data)
 Reads a page of data from an emulated RWW EEPROM memory page. More...
 
enum status_code rww_eeprom_emulator_write_buffer (const uint16_t offset, const uint8_t *const data, const uint16_t length)
 Writes a buffer of data to the emulated RWW EEPROM memory space. More...
 
enum status_code rww_eeprom_emulator_write_page (const uint8_t logical_page, const uint8_t *const data)
 Writes a page of data to an emulated RWW EEPROM memory page. More...
 

Variables

static struct _rww_eeprom_module _eeprom_instance
 Internal RWW EEPROM emulator instance. More...
 

#define CONF_LOGICAL_PAGE_NUM_IN_ROW   RWWEE_LOGICAL_PAGE_NUM_1

Configuration option, one logical page stored in a physical row.

Referenced by _rww_eeprom_emulator_format_memory(), _rww_eeprom_emulator_is_full_row(), _rww_eeprom_emulator_move_data_to_spare(), and rww_eeprom_emulator_init().

#define CONF_PAGE_CHECKSUM_ENABLE   false
#define RWW_EEPROM_MAGIC_KEY   {0x41744545, 0x50524f4d, 0x456d752d,0x5257572e}

Magic key is the sequence "AtEEPROMEmu_RWW." in ASCII. The key is encoded as a sequence of 32-bit values to speed up checking of the key, which can be implemented as a number of simple integer comparisons,

Referenced by _rww_eeprom_emulator_create_master_page(), and _rww_eeprom_emulator_verify_master_page().

#define RWW_EEPROM_MAGIC_KEY_COUNT   4

Length of the magic key, in 32-bit elements.

Referenced by _rww_eeprom_emulator_create_master_page(), and _rww_eeprom_emulator_verify_master_page().

#define RWW_EEPROM_MAX_LOGICAL_PAGES
Value:
(((NVMCTRL_RWWEE_PAGES - (2 * NVMCTRL_ROW_PAGES)) \
/ NVMCTRL_ROW_PAGES) * CONF_LOGICAL_PAGE_NUM_IN_ROW)
#define CONF_LOGICAL_PAGE_NUM_IN_ROW
Configuration option, one logical page stored in a physical row.
Definition: rww_eeprom.c:46

RWW EEPROM max logical page num.

Referenced by rww_eeprom_emulator_init().

static void _rww_eeprom_emulator_check_logical_page ( void  )
static

Check if there exist rows with same logical pages due to power drop when writing or erasing page.

when existed same logical page, if the new row checksums is valid, the old(full) row will be erased, or the new row will be erased. If page checksum disabled, the old(full) row will be erased.

References _rww_eeprom_emulator_erase_invalid_page(), _rww_eeprom_page::header, i, j, _rww_eeprom_page::logical_page, _rww_eeprom_module::physical_pages, and _rww_eeprom_module::rwwee_addr.

Referenced by _rww_eeprom_emulator_update_page_mapping().

static void _rww_eeprom_emulator_erase_invalid_page ( uint16_t  pre_phy_page,
uint16_t  next_phy_page 
)
static

Erase one invalid page according to two invalid physical page.

Parameters
[in]pre_phy_pageOne physical invalid page
[in]next_phy_pageAnother physical invalid page

References _rww_eeprom_emulator_is_full_row(), _rww_eeprom_emulator_nvm_erase_row(), _rww_eeprom_emulator_nvm_read_page(), and CONF_PAGE_CHECKSUM_ENABLE.

Referenced by _rww_eeprom_emulator_check_logical_page().

static bool _rww_eeprom_emulator_is_full_row ( uint16_t  phy_page)
static

Check if a row is a full row because the page is a invalid page, so if two pages have data, it is the full row.

Parameters
[in]phy_pagePhysical page that in a row

References CONF_LOGICAL_PAGE_NUM_IN_ROW, _rww_eeprom_page::header, _rww_eeprom_page::logical_page, _rww_eeprom_module::rwwee_addr, and RWWEE_LOGICAL_PAGE_NUM_1.

Referenced by _rww_eeprom_emulator_erase_invalid_page().

static bool _rww_eeprom_emulator_is_page_free_on_row ( const uint8_t  start_physical_page,
uint8_t *const  free_physical_page 
)
static

Finds the next free page in the given row if one is available.

Parameters
[in]start_physical_pagePhysical page index of the row to search
[out]free_physical_pageIndex of the physical page that is currently free (if one was found)
Returns
Whether a free page was found in the specified row.
Return values
\ctrue If a free page was found
\cfalse If the specified row was full and needs an erase

References _rww_eeprom_page::header, _rww_eeprom_page::logical_page, and _rww_eeprom_module::rwwee_addr.

Referenced by rww_eeprom_emulator_write_page().

static enum status_code _rww_eeprom_emulator_move_data_to_spare ( const uint8_t  row_number,
const uint8_t  logical_page,
const uint8_t *const  data 
)
static

Moves data from the specified logical page to the spare row.

Moves the contents of the specified row into the spare row, so that the original row can be erased and re-used. The contents of the given logical page is replaced with a new buffer of data.

Parameters
[in]row_numberPhysical row to examine
[in]logical_pageLogical RWW EEPROM page number in the row to update
[in]dataNew data to replace the old in the logical page
Returns
Status code indicating the status of the operation.

References _rww_eeprom_emulator_nvm_erase_row(), _rww_eeprom_emulator_nvm_fill_cache(), _rww_eeprom_emulator_nvm_read_page(), _rww_eeprom_module::cache, _rww_eeprom_module::cache_active, CONF_LOGICAL_PAGE_NUM_IN_ROW, _rww_eeprom_page::data, _rww_eeprom_page::header, i, _rww_eeprom_page::logical_page, _rww_eeprom_module::page_map, rww_eeprom_emulator_commit_page_buffer(), RWW_EEPROM_PAGE_SIZE, _rww_eeprom_module::rwwee_addr, _rww_eeprom_module::spare_row, and STATUS_OK.

Referenced by rww_eeprom_emulator_write_page().

static void _rww_eeprom_emulator_nvm_commit_cache ( const uint16_t  physical_page)
static

Commits the internal NVM controller page buffer to physical memory.

Parameters
[in]physical_pagePhysical page in RWW EEPROM space to commit

References NVM_COMMAND_RWWEE_WRITE_PAGE, nvm_execute_command(), _rww_eeprom_module::rwwee_addr, STATUS_BUSY, and STATUS_OK.

Referenced by _rww_eeprom_emulator_create_master_page(), _rww_eeprom_emulator_format_memory(), and rww_eeprom_emulator_commit_page_buffer().

static void _rww_eeprom_emulator_nvm_erase_row ( const uint8_t  row)
static

Erases a given row within the physical RWW EEPROM memory space.

Parameters
[in]rowPhysical row in RWW EEPROM space to erase

References nvm_erase_row(), _rww_eeprom_module::rwwee_addr, STATUS_BUSY, and STATUS_OK.

Referenced by _rww_eeprom_emulator_create_master_page(), _rww_eeprom_emulator_erase_invalid_page(), _rww_eeprom_emulator_format_memory(), and _rww_eeprom_emulator_move_data_to_spare().

static void _rww_eeprom_emulator_nvm_fill_cache ( const uint16_t  physical_page,
const void *const  data 
)
static

Fills the internal NVM controller page buffer in physical RWW EEPROM memory space.

Parameters
[in]physical_pagePhysical page in RWW EEPROM space to fill
[in]dataData to write to the physical memory page

References _rww_eeprom_emulator_page_checksum(), CONF_PAGE_CHECKSUM_ENABLE, _rww_eeprom_page::data, _rww_eeprom_page::header, _rww_eeprom_module::initialized, nvm_write_buffer(), _rww_eeprom_page::page_checksum, _rww_eeprom_module::rwwee_addr, STATUS_BUSY, and STATUS_OK.

Referenced by _rww_eeprom_emulator_create_master_page(), _rww_eeprom_emulator_format_memory(), _rww_eeprom_emulator_move_data_to_spare(), and rww_eeprom_emulator_write_page().

static bool _rww_eeprom_emulator_nvm_read_page ( const uint16_t  physical_page,
void *const  data 
)
static

Reads a page of data stored in physical RWW EEPROM memory space.

Parameters
[in]physical_pagePhysical page in RWW EEPROM space to read
[out]dataDestination buffer to fill with the read data
Returns
Whether the page data checksum is correct.
Return values
\ctrue The page data checksum is correct
\cfalse The page data checksum is wrong

References _rww_eeprom_emulator_page_checksum(), CONF_PAGE_CHECKSUM_ENABLE, _rww_eeprom_page::data, _rww_eeprom_page::header, _rww_eeprom_module::initialized, nvm_read_buffer(), _rww_eeprom_page::page_checksum, _rww_eeprom_module::rwwee_addr, STATUS_BUSY, and STATUS_OK.

Referenced by _rww_eeprom_emulator_erase_invalid_page(), _rww_eeprom_emulator_move_data_to_spare(), _rww_eeprom_emulator_verify_master_page(), and rww_eeprom_emulator_read_page().

static uint8_t _rww_eeprom_emulator_page_checksum ( const uint8_t *  buffer)
static

RWW EEPROM Page Checksum.

Parameters
[in]bufferPointer of page data
Returns
Checksum result.

References i, and RWW_EEPROM_PAGE_SIZE.

Referenced by _rww_eeprom_emulator_nvm_fill_cache(), and _rww_eeprom_emulator_nvm_read_page().

static enum status_code _rww_eeprom_emulator_verify_master_page ( void  )
static

Verify the contents of a master RWW EEPROM page.

Verify the contents of a master RWW EEPROM page to ensure that it contains the correct information for this version of the RWW EEPROM emulation service.

Return values
STATUS_OKGiven master page contents is valid
STATUS_ERR_BAD_FORMATMaster page contents was invalid
STATUS_ERR_IOMaster page indicates the data is incompatible with this version of the RWW EEPROM emulator

References _rww_eeprom_emulator_nvm_read_page(), _rww_eeprom_master_page::emulator_id, _rww_eeprom_master_page::magic_key, _rww_eeprom_master_page::major_version, _rww_eeprom_master_page::minor_version, RWW_EEPROM_EMULATOR_ID, RWW_EEPROM_MAGIC_KEY, RWW_EEPROM_MAGIC_KEY_COUNT, RWW_EEPROM_MAJOR_VERSION, RWW_EEPROM_MINOR_VERSION, STATUS_ERR_BAD_FORMAT, STATUS_ERR_IO, and STATUS_OK.

Referenced by rww_eeprom_emulator_init().

COMPILER_PACK_RESET ( )
COMPILER_PACK_SET ( )

struct _rww_eeprom_module _eeprom_instance
static
Initial value:
= {
.initialized = false,
}

Internal RWW EEPROM emulator instance.