
  /*
   *  Object %CRYS_NVS.h   : %
   *  State           :  %state%
   *  Creation date   :  Tue Nov 23 09:29:27 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *
   *  \version CRYS_NVS.c#1:csrc:1
   *  \author adams
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */



/************* Include Files ****************/
#ifdef DX_SEP_SIMULATION
	#include "nvs_host_duplicate_wrapper.h"
#endif 
#include "NVS.h"
#include "DX_VOS_File.h"

#ifdef NVS_DEBUG_MODE_ENABLED
    #include "nvs_debug.h"
#endif
/************************ Defines ******************************/


/* number of elements in the array */
#define NVS_MAP_ARRAY_LEN 10

/************************ Enums ******************************/


/************************ Typedefs ******************************/


/************************ Global Data ******************************/

/************* Private function prototype ****************/


/************************ Public Functions ******************************/

static NVS_Mapping_t  s_MapArray[NVS_MAP_ARRAY_LEN];

/************************ Public Functions ******************************/

/* ************** TODO – need to be implemented by the user ********************** */
/**
 * @brief NVS_Init creates a mapping for the fileId input parameter. MemoryId is a token that defines the actual file.
 *        Each application that uses NVS associat the file(fileId) that it is working with , with the some token. 
 *        Application sees only the token, and the mapping between the token and the fileId will be done by NVS
 *        For example, the main storage of the SST may have the memoryId of 1 (that is how SST will see it), and the fileId will be 
 *        file descriptor of the actual file. when NVS recieves request from application , it will translate the memory Id into the file id.
 *
 * @param[in] fileId        - the fileId whose mapping to memory id will be returned in the memoryId_ptr.
 * @param[out] memoryId_ptr          - will hold the allocated memory id.
 *
 * @return DxError_t - On success the value DX_SUCCESS is returned, 
 *                     On failure the following values:
 *
 *                     NVS_MEMORY_ID_ALREADY_EXIST_ERROR - the memory id already exists
 *                     NVS_MEMORY_ALOCC_FAILURE - the buffers that holds the mapping is already full.
 */
DxError_t NVS_InitFile(DxUint32_t       fileId,
                       DxNvsMemoryId_t  memoryId)
{
  /* error */
  DxError_t   error;
   
  /*-----------------------
    CODE
  ---------------------------*/ 
  
  error = DX_SUCCESS;
  
  if(memoryId >= NVS_MAP_ARRAY_LEN)
  {
    error = NVS_MEMORY_ID_NOT_EXIST_ERROR;
	  goto end_function;
  }
  
  /* set the mapping  - memory id is index into array, but from user point of view array start from 1*/
  s_MapArray[memoryId - 1].validFlag = 1;
  s_MapArray[memoryId - 1].fileId = fileId;
  
end_function:

  return error;
}

/* ************** TODO – need to be implemented by the user ********************** */
/**
 * @brief NVS_GetMemoryId returns the memory Id for the given file id. If mapping does not exists for the given file Id, then error is returned
 * @param[in] fileId        - the fileId whose mapped to memory idis required.
 * @param[out] memoryId_ptr          - will hold the found memory id.
 *
 * @return DxError_t - On success the value DX_SUCCESS is returned, 
 *                     On failure the following values:
 *
 *                     NVS_MEMORY_ID_ALREADY_EXIST_ERROR - the memory id already exists
 *                     NVS_MEMORY_ALOCC_FAILURE - the buffers that holds the mapping is already full.
 */                       
DxError_t NVS_GetMemoryId(DxUint32_t        fileId,
                          DxNvsMemoryId_t*  memoryId_ptr)
{
  /* error */
  DxError_t   error;
  
  /* count */
  DxUint32_t  count;
  
  /*--------------------------
      CODE
  ----------------------------*/
  
  error = DX_SUCCESS;
  
  for(count = 0; count < NVS_MAP_ARRAY_LEN; count++)
  {
    if(s_MapArray[count].fileId == fileId)
    {
      break;
    }
  }
  
  if(count >= NVS_MAP_ARRAY_LEN)
  {
    error = NVS_MEMORY_ID_NOT_EXIST_ERROR;
    goto end_function;
  }
  
  *memoryId_ptr = (count + 1);
  
end_function:

  return error;

}

/**
 * @brief NVS_Read receives an offset, in bytes, from the beginning of the allocated
 * non-volatile memory space, a destination buffer and its size (also in bytes) 
 * and reads into it from the flash memory. This function returns the number of 
 * Bytes actually read or an Error Code if failed.
 *
 *
 * @param[in] memoryId        - the non volatile memory id - to this memory the NVS driver is accessing.
 * @param[in] offset          - offset, in bytes, from the base address in the flash to be read
 * @param[in] buffer_ptr      - Pointer to the destination buffer
 * @param[in] buff_len        - Number of bytes to read from the momory
 * @param[out] bytes_read_ptr - Number of bytes that are read. 
 *
 * @return DxError_t - On success the value DX_SUCCESS is returned, 
 *                     On failure the following values:
 *
 *                     NVS_MEMORY_ID_NOT_EXIST_ERROR - the memory device doesnt exist.
 *                     NVS_MEMORY_ACCESS_FAILURE - failing to access the memory.
 */
DxError_t NVS_Read(DxNvsMemoryId_t  memoryId,      /* the non volatile memory id - to this memory the NVS driver is accessing */
                   DxUint32_t       offset,           /*The source address in the non volatile memory where to copy the data from*/
                   char*            buffer_ptr,            /* Pointer to destination buffer. */
                   DxUint32_t       buff_len,         /* Number of Bytes to read from the Flash */
                   DxUint32_t*      bytes_read_ptr)  /* Number of bytes that are read */
{
  /* error code */
	DxError_t error;
  
  /* file id */
  DxUint32_t  fileId;

  /*-------------------------
      CODE
  ------------------------------*/
  
  error = DX_SUCCESS;
  
  #ifdef NVS_DEBUG_MODE_ENABLED
    
  error = NVS_DebugOpFail(NVS_DBG_OP_READ);
  if( error != DX_SUCCESS )
  {
    goto Exit;
  }
  #endif //NVS_DEBUG_MODE_ENABLED
  
  if(memoryId >= NVS_MAP_ARRAY_LEN)
  {
    error = NVS_MEMORY_ID_NOT_EXIST_ERROR;
	  goto Exit;
  }
  
  fileId = s_MapArray[memoryId - 1].fileId;
  
  /* setting the file to the offset */	 
  error = DX_VOS_FSeek( (DxVosFile)fileId, offset);

  if( error != DX_SUCCESS )
  {
	  goto Exit;
  }
  
  /* reading the data from the file */
  error = DX_VOS_FReadEx( (DxVosFile)fileId , (char *)buffer_ptr , buff_len , bytes_read_ptr );

Exit:

  /* on error case set the number of butes read as 0 and return error code */  
  if( error != DX_SUCCESS )
  {
    *bytes_read_ptr = 0;
    return NVS_MEMORY_ACCESS_FAILURE;
  }

  return DX_SUCCESS;

}/* END OF NVS_Read */  


/**
 * @brief NVS_Write receives an offset, in bytes, from the beginning of the allocated 
 * non-volatile memory space, a source buffer and its size (also in bytes) 
 * and writes it to the flash memory. This function returns the number of bytes actually 
 * written or an Error Code if failed.
 *
 *
 * @param[in] memoryId        - the non volatile memory id - to this memory the NVS driver is accessing.
 * @param[in] offset          - offset, in bytes, from the base address in the flash to be read
 * @param[in] buffer_ptr      - Pointer to the destination buffer
 * @param[in] buff_len        - Number of bytes to write to the memory
 * @param[out] bytes_written  - Number of bytes written 
 *
 * @return DxError_t - On success the value DX_SUCCESS is returned, 
 *                     On failure the following values:
 *
 *                     NVS_MEMORY_ID_NOT_EXIST_ERROR - the memory device doesnt exist.
 *                     NVS_MEMORY_ACCESS_FAILURE - failing to access the memory.
 */
DxError_t NVS_Write(DxNvsMemoryId_t memoryId,      /* the non volatile memory id - to this memory the NVS driver is accessing */
                    DxUint32_t      offset,           /*The source address in the non volatile memory where to copy the data from*/
                    char*           buffer_ptr,            /* Pointer to destination buffer. */
                    DxUint32_t      buff_len,         /* Number of bytes to write to the memory */
                    DxUint32_t*     bytesWritten)    /* Number of bytes that were written */
{
  /* error code */
  DxError_t error;
  
  /* file id */
  DxUint32_t  fileId;

  /*----------------------------------
      CODE
  -------------------------------------*/
  
  #ifdef NVS_DEBUG_MODE_ENABLED
        
  error = NVS_DebugOpFail(NVS_DBG_OP_WRITE);
  if( error != DX_SUCCESS )
  {
    goto Exit;
  }
 
  #endif //NVS_DEBUG_MODE_ENABLED
  
  if(memoryId >= NVS_MAP_ARRAY_LEN)
  {
    error = NVS_MEMORY_ID_NOT_EXIST_ERROR;
	  goto Exit;
  }
  
  fileId = s_MapArray[memoryId - 1].fileId;

  /* initialize the bytes written to the buffer size */ 
  *bytesWritten = buff_len;

  /* setting the file to the offset */	 
  error = DX_VOS_FSeek( (DxVosFile)fileId, offset);

  if( error != DX_SUCCESS )
  
	  goto Exit;

  /* writing the data to the file */
  error = DX_VOS_FWrite( (DxVosFile)fileId, buffer_ptr , buff_len );

  if( error != DX_SUCCESS )
  {
	  goto Exit;
  }

  /* flushing the data to the file */
  error = DX_VOS_FFlush((DxVosFile)fileId);

Exit:

  /* on error case set the number of butes read as 0 and return error code */  
  if( error != DX_SUCCESS )
  {
     *bytesWritten = 0;
	   return NVS_MEMORY_ACCESS_FAILURE;
  }

  return DX_SUCCESS;

}/* END OF NVS_Write */


