/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::   Module      :   Mem read/write functions
::   Copyright   :   (C)2003-2009 Woodward
::   Platform(s) :   MPC5xx
::   Limitations :   None
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*! \file MemFuncs.h
    \brief Virtual memory access functions that allow access to standard as well as non-standard memories (like
           serial EEPROM). See \ref memoryaccess. */

#ifndef __MEMFUNCS_H
#define __MEMFUNCS_H

/* --- INCLUDE FILES ----------------------------------------------------------------------------------------*/
#include <typedefn.h>

/* --- DEFINES ----------------------------------------------------------------------------------------------*/

/* --- TYPEDEF ----------------------------------------------------------------------------------------------*/
#pragma pack(1)

/*! Enumeration describes some of the possible memory access exceptions. Application code should check for the
    \ref EXCEPTION_NONE value to confirm whether the access was successful of not. The rest of the values indicate
    an error and a possible cause */
typedef enum
{
    EXCEPTION_NONE,                 /*!< (0) No exception occurred. This describes the success value */
    EXCEPTION_FRAMING,              /*!< (1) A framing error resulted while reading from a serial device */
    EXCEPTION_NOISE,
    EXCEPTION_OVERRUN,              /*!< (3) The access failed because a hardware buffer overran */
    EXCEPTION_RXERROR,
    EXCEPTION_BUF_OVRUN,            /*!< (5) The acess failed because a buffer used in the access suffered from an overrun condition */
    EXCEPTION_ILL_CCODE,
    EXCEPTION_WRTE_FAIL,            /*!< (7) An unspecified write failure occurred */
    EXCEPTION_READ_FAIL,            /*!< (8) An unspecified read failure occurred */
    EXCEPTION_IN_PROGRESS,          /*!< (9) The access is pending */
    EXCEPTION_VPP_ERR,              /*!< (10) A memory write failed because the programming voltage was not present */
    EXCEPTION_ERASE_FAIL,           /*!< (11) A write failed because the memory cell could not be successfully erased */
    EXCEPTION_ACC_DENIED,           /*!< (12) Access to memory was denied because of insufficient privledges or because inappropriate data was supplied */
    EXCEPTION_ADDR_ERROR,           /*!< (13) The memory access failed because the supplied address was not legal. */
    EXCEPTION_PKT_TMO,
    EXCEPTION_BYTE_TMO,
    EXCEPTION_CHKSUM,
    EXCEPTION_REC_COUNT,
    EXCEPTION_BAD_PROT,
    EXCEPTION_SRECORDFORMATNOT64,
    EXCEPTION_PROCESSOR_UNSUPPORTED,
    EXCEPTION_MISALIGNED,           /*!< (21) Data alignment issue resulted in the access failing. This error could result when accessing a memory device that
                                         is known to only support 16bit aligned accessed yet the supplied address did not meet this alignment condition */
    EXCEPTION_VERIFY_FAIL,          /*!< (22) A write access failed because the data written did not match what was read from the memory once the write had completed.
                                         Most non-volatile memories can only support a certain number of erase-write cycles, after which cells begin to fail */
    EXCEPTION_QUEUE_OVFLOW,         /*!< (23) An internal queue used to schedule access has overflown */
    EXCEPTION_BUFFER_RANGE,
    EXCEPTION_MULTIPLE_IN_USE,      /*!< (25) An attempt was made to write to a block that is in use by another service. For example, attempting to write to a block that
                                              is currently under going erasure */
    EXCEPTION_MULTIPLE_UNSUPPORTED, /*!< (26) An attempt was made to schedule multiple accesses to a memory device that the Framework does not support multiple accesses for. */
    EXCEPTION_MULTIPLE_PAGE_ALIGNMENT,
    EXCEPTION_MULTIPLE_PAGES_IN_BLOCK,
    EXCEPTION_MULTIPLE_ADDRESS_ORDER,
    EXCEPTION_UNREGISTERED_HANDLER,
    EXCEPTION_READ_FAIL_OUTOFMEM,   /*!< (31) Dynamic memory was required but could not be obtained */
    EXCEPTION_READ_FAIL_CALL,       /*!< (32) Memory access function to read was called from an illegal thread priority */
    EXCEPTION_READ_FAIL_TIMEOUT,    /*!< (33) A timeout occurred before the read would complete */
    EXCEPTION_WRTE_FAIL_CALL,       /*!< (34) Memory access function to write was called from an illegal thread priority */
    EXCEPTION_WRTE_FAIL_TIMEOUT,    /*!< (35) A timeout occurred before the write would complete */
    EXCEPTION_ERASE_ERROR,          /*!< (36) The request to erase the specifed memory failed. Most non-volatile memories can only support a certain number of
                                              erase-write cycles, after which cells begin to fail */
    EXCEPTION_OUT_OF_MEM,           /*!< (37) The access required the use of dynamic memory and there was insufficient memory available to complete the access */
    EXCEPTION_DEVICE_UNSUPPORTED,   /*!< (38) The memory access failed because the device is not supported by hardware that the application is executing on. */
    EXCEPTION_ERASE_NOTAPPLICABLE,  /*!< (39) An attempt to erase a memory failed because the memory does not require erasure */

} E_Exceptions;

/*! Asynchronous memory access notification function type. The \p pResultBuffer parameter holds a pointer to an addressable buffer of size \p uBytesAffected
    that contains the result of the memory access. For a read it is the values read, for a write it describes the data currently in the non-volatile memory
    store, even if that data is not representative of what was to be written. \p eException describes the exception state for the memory access that made
    this notification. Checking for \ref EXCEPTION_NONE indicates that the access was successful. \p uAppDataSentOnNotify is data that was supplied by the
    application when the asynchronous memory request was issued. */
typedef void (*MemFuncCBackPtr)(void const* pResultBuffer, uint4 uBytesAffected, E_Exceptions eException, NativePtrSizedInt_U uAppDataSentOnNotify);

/*! \brief Enumeration describes the set of mask definitions that are used to identify which attributes are valid
           within the \ref S_MemQuery data structure and consequently which attributes will be recovered by a
           MemQuery() request.

Each mask definition applies to a particular member of the data structure.
\code
    ...
    S_MemQuery QueryObj;
    S_MemBlockDefn MyMemBlock = { MyMemBlockStart, MyMemBlockSizeInBytes };

    // Going to query for the erase status of a single block that is described by an address
    QueryObj.uValidAttributesMask = MEM_ERASE_STATUS;
    QueryObj.pMemBlock = &MyMemBlock;
    // The remainder of the data structure can be left undefined since the uValidAttributesMask
    //   indicates that the members are not valid
    ... \endcode */
typedef enum
{
/*! Indicates that the S_MemQuery::eEraseStatus member is to be filled by a MemQuery().  */
    MEM_ERASE_STATUS = 0x01,      

/* IF THIS TYPE EXCEEDS 0x80 THEN ALTER THE MemQueryValidAttributes_U TYPE ACCORDINGLY */

} E_MemQueryValidAttributes;

typedef uint1 MemQueryValidAttributes_U;

/*! \brief Describes the erasure status of a memory block. */
typedef enum
{
    ERASE_STATE_NA,             /*!< The memory does not have an erasure state so this state is not applicable. Such memories do not need
                                     to be erased before they can be modified. RAM and EEPROM type memories are examples. */
    ERASE_STATE_ILLEGAL,        /*!< The memory range that was queried for erasue status is not legal. The memory may not be supported by
                                     the hardware, or the address does not map to a legal, singular device */
    ERASE_STATE_NOT_ERASED,     /*!< The memory block is not erased. Some types of memory like FLASH may not write reliably if the
                                      memory block is not in the erased state. */
    ERASE_STATE_ERASED,         /*!< The memory block is erased. */
    ERASE_STATE_ERASING,        /*!< The memory block is currently being erased. */
} E_MemEraseStatus;

/*! \brief Describes the constant attributes of a memory block */
typedef struct
{
    void* StartAddr;        /*!< The starting address of the memory block */
    uint4 uSizeInBytes;     /*!< The size of the memory block in bytes */
} S_MemBlockDefn;

/*! \brief Memory query data structure.

 Use with the MemQuery() function to learn about attributes of a defined memory block. */
typedef struct
{
/*! Logic-OR the attributes [\ref MEM_ERASE_STATUS] that are valid for this instance of the data structure */
    MemQueryValidAttributes_U uValidAttributesMask;
/*! Set this attribute to define the memory block that is to be queried. This is a required attribute. */
    S_MemBlockDefn const* pMemBlock;
/*! Describes the erasure state of the memory block described by the Use the S_MemQuery::pMemBlock member. 
    Use the \ref MEM_ERASE_STATUS mask to indicate that an erasure status query is to be performed. */
    E_MemEraseStatus eEraseStatus;
} S_MemQuery;

#pragma pack()

/*---- EXTERNALS --------------------------------------------------------------------------------------------*/

/*---- PROTOTYPES -------------------------------------------------------------------------------------------*/
bool1 MemWrite(void *AddrToWrite, void const* pDataBuffer, uint4 in_uNumBytesToWrite, MemFuncCBackPtr pfNotifyOnWriteComplete, NativePtrSizedInt_U uAppDataSendOnNotify);
bool1 MemRead(void *AddrToRead, uint4 in_uNumBytesToRead, MemFuncCBackPtr pfNotifyOnReadComplete, NativePtrSizedInt_U uAppDataSendOnNotify);

E_Exceptions MemErase(void *AddrToErase, uint4 in_uMinBytesToErase, MemFuncCBackPtr pfNotifyOnEraseComplete, NativePtrSizedInt_U uAppDataSendOnNotify);
E_Exceptions MemQuery(S_MemQuery*);


E_Exceptions MemInit(void);
E_Exceptions MemInitStatus(void);
E_Exceptions MemClose(void (*Address)(void));

#endif /* __MEMFUNCS_H*/

/*---- END OF FILE ----------------------------------------------------------------------------------------*/

