/** \dir NVM
 *
 *  \brief Non-Volatile Memory
 *
 *  This directory/namespace contains all the software used to manage non-volatile memory for this CPU.
 *
 */

/** \file
 *  \brief This file defines the interface to the NVM package.
 *
 *  This file should be included by any file outside the NVM package wishing to make use
 *  of any of the NVM functionality.
 */

#ifndef NVM_H
#define NVM_H
    
#ifdef __cplusplus
extern "C" {
#endif

/* Preprocessor and Type Definitions */

//! Enumeration of the various states of a nonvolatile memory entry.
typedef enum
{
    //! This entry has not yet been initialized.
    NVM_STATE_UNINITIALIZED = 0,
    
    //! This entry has been read from nonvolatile memory, and the cyclic redundancy check failed.
    NVM_STATE_CRC_FAILED,
    
    //! No changes are pending for this entry.
    NVM_STATE_IDLE,

    //! A request has been made to save this entry to NVM.
    NVM_STATE_SAVE_REQUESTED
} NVM_Entry_State_T;


typedef struct
{
    // Size of the NVM data.
    const size_t Size;

    // Address of the NVM data in the EEPROM memory.
    const uint16_t EE_Address;

    // Address of the calculated CRC value in the EEPROM memory.
    const uint16_t EE_CRC_Address;

    // Address of the NVM data in RAM.
    uint8_t * const Value;

    // Address of the default data in ROM.
    uint8_t const * const Default;

    // Current state of this NVM entry
    NVM_Entry_State_T State;

} NVM_EEPROMEntry_T;


/* Include Files */
#include "NVM_CRC.h"

#if (CONFIG__HAS_EXTERNAL_NVM)
#include "NVM_ExternalEEPROM.h"
#include "NVM_ExternalEEPROMEntries.h"
#endif // CONFIG__HAS_EXTERNAL_NVM

#if (CONFIG__HAS_INTERNAL_NVM)
#include "NVM_OnChipEEPROM.h"
#include "NVM_OnChipEEPROMEntries.h"
#endif // CONFIG__HAS_INTERNAL_NVM

/* Public Variables */

/* Public Functions */

inline bool IsNVMInitialized()
{    
    taskENTER_CRITICAL();
    bool is_initialized =
    
#if (CONFIG__HAS_EXTERNAL_NVM)
    NVM_IsExternalEEPROMInitialized &&
#endif // CONFIG__HAS_EXTERNAL_NVM

#if (CONFIG__HAS_INTERNAL_NVM)
    NVM_IsOnChipEEPROMInitialized &&
#endif // CONFIG__HAS_INTERNAL_NVM

    true;
    taskEXIT_CRITICAL();

    return is_initialized;
}

#ifdef __cplusplus
}
#endif

#endif // NVM_H