/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * =======================================================================
 *  The routines in this file are wrappers around our flash driver so that flash
 *  can be used instead of nvram. The last sector of flash will be used for NVRAM.
 *  Its up to the user to make sure nothing else writes to this sector.
 *
 * When      Who    What
 * =============    ============================================================
 * 11-06-02  CHG    Removed mallocs from NANVInit() and NANVmemset() since this
 *                  code will be used in bootloader and malloc library is too
 *                  large.
 * 
 */
#include "bsp_drivers.h"
#include "npttypes.h"
#if (BSP_NVRAM_DRIVER == BSP_NVRAM_LAST_FLASH_SECTOR)
#include <stdio.h>
#include "narmnvrm.h"
#include "naflash.h"
#include "Flash.h"
// #include "bsp_api.h"
#include "ncc_init.h"
#include "string.h"

/*
 * Global variables used for range checking.
 */ 

/*#define DEBUG_NV_FLASH */
static unsigned long nv_flash_inited = 0;
static unsigned long nv_flash_sector = 0;
static unsigned long nv_flash_sector_backup = 0;
static unsigned long nv_flash_sector_size = 0;

/*
 *
 *  Function: void NANVInit (char *basep, unsigned long range)
 *
 *  Description:
 *
 *  This function calls NAFlashSectors and NAFlashSectorSizes and sets the global
 *  vars nv_flash_sector and nv_flash_sector_size.
 *  This function must be called first.
 *  Parameters:
 *
 *      basep       ignored
 *      range       ignored
 *
 *  Return Values:
 *
 *      none
 *
 */
void NANVInit (char *basep, unsigned long range)
{
    int num_of_flash_sectors;
    static unsigned long sectorSizeArray[MAX_SECTORS];
    static unsigned long sectorSizeoffset[MAX_SECTORS];
    NA_UNUSED_PARAM(basep);
    NA_UNUSED_PARAM(range);
    if (nccRomImageBuild() == 0)
    {
    num_of_flash_sectors = NAFlashSectors();
    nv_flash_sector = num_of_flash_sectors - 1;
    nv_flash_sector_backup = num_of_flash_sectors - 2;
    
    NAFlashSectorSizes ( sectorSizeArray );
    NAFlashSectorOffsets ( sectorSizeoffset );
    nv_flash_sector_size = sectorSizeArray[nv_flash_sector];
#ifdef DEBUG_NV_FLASH    
	printf("nv_flash_sector  %d\n",nv_flash_sector);
	printf("nv_flash_sector_backup  %d\n",nv_flash_sector_backup);
	printf("nv_flash_sector_size = 0x%x\n",nv_flash_sector_size);
	printf("nv_flash_sector_offset = 0x%x\n",sectorSizeoffset[nv_flash_sector]);
#endif	
	nv_flash_inited = 1;
    }
    else
    {
#ifdef DEBUG_NV_FLASH    
	printf("NANVInit ERROR: Cannot use Flash as NVRAM when running image on the Flash.\n");
#endif	
    }
    return;
}

/*
 *
 *  Function: int NANVWrite (unsigned long offset, char *buffer, unsigned long length)
 *
 *  Description:
 *
 *  This function calls NAFlashWrite()
 *
 *  Parameters:
 *
 *      offset          position in NVRAM to start write
 *      buffer          pointer to buffer to write
 *      length          number of bytes to write
 *
 *  Return Values:
 *
 *      0       Success
 *      -1      A bounds error occurred.
 *
 */
int NANVWrite (unsigned long offset, char *buffer, unsigned long length)
{
    int result;

    if((offset + length) > nv_flash_sector_size)
	return -1;

	if (nv_flash_inited == 0)
	{
#ifdef DEBUG_NV_FLASH
		printf("NANVWrite ERROR: nv_flash not initialized!\n"
			   "nv_flash_sector=%d, nv_flash_sector_backup=%d\n",
			   nv_flash_sector, nv_flash_sector_backup);
#endif
		return -1;
	}
    
    result = NAFlashWrite( nv_flash_sector ,offset, length, buffer,  ERASE_AS_NEEDED);

    if ( result == NAFLASH_SUCCESS)    
	return 0;
    else
    {
#ifdef DEBUG_NV_FLASH
	printf("NANVWrite ERROR : NAFlashWrite failed errno: %d\n",result);
#endif 
	return -1;
    }
}


/*
 *
 *  Function: int NANVRead (unsigned long offset, char *buffer, unsigned long maxlength)
 *
 *  Description:
 *
 *  This function calls NAFlashRead()
 *
 *  Parameters:
 *
 *      offset          position in NVRAM to start read at
 *      buffer          pointer to buffer to load with data
 *      maxlength       number of bytes to read
 *
 *  Return Values:
 *
 *      -1              Invalid parameters supplied
 *      !-1             number of bytes read.
 *
 */
int NANVRead (unsigned long offset, char *buffer, unsigned long maxlength)
{
    int result;

    if((offset + maxlength)> nv_flash_sector_size )
	return -1;

	if (nv_flash_inited == 0)
	{
#ifdef DEBUG_NV_FLASH
		printf("NANVRead ERROR: nv_flash not initialized!\n"
			   "nv_flash_sector=%d, nv_flash_sector_backup=%d\n",
			   nv_flash_sector, nv_flash_sector_backup);
#endif
		return -1;
	}
    
    result = NAFlashRead( nv_flash_sector ,offset, maxlength,buffer);
  	
    if ( result == NAFLASH_SUCCESS)    
	return 0;
    else
    {
#ifdef DEBUG_NV_FLASH
	printf("NANVRead ERROR : NAFlashRead failed errno: %d\n",result);
#endif 
	return -1;
    }

}


/*
 *
 *  Function: void NANVmemset (char data)
 *
 *  Description:
 *
 *  This function calls NAFlashWrite() with the ERASE_AS_NEEDED option
 *  and writes the char passed in to the entire space reserved in flash
 *  for NVRAM.
 *
 *  Parameters:
 *
 *      data        value to write to NVRAM
 *
 *  Return Values:
 *
 *      none
 *
 */
void NANVmemset (char data)
{
    char buffer[100];
    int result;
    unsigned long bytesWritten = 0;
    
 	if (nv_flash_inited == 0)
	{
#ifdef DEBUG_NV_FLASH
		printf("NANVmemset ERROR: nv_flash not initialized!\n"
			   "nv_flash_sector=%d, nv_flash_sector_backup=%d\n",
			   nv_flash_sector, nv_flash_sector_backup);
#endif
	    return;
	}
    
    memset(buffer, data, sizeof(buffer));
    
    while (bytesWritten < nv_flash_sector_size)
    {
        unsigned long bytesToWrite = (nv_flash_sector_size - bytesWritten);
        
        if (bytesToWrite > sizeof(buffer))
        {
            bytesToWrite = sizeof(buffer);
        }
        
        result = NAFlashWrite( nv_flash_sector, (WORD32) bytesWritten, (WORD32) bytesToWrite, buffer, ERASE_AS_NEEDED);
    
        if (result != NAFLASH_SUCCESS)
        {
    #ifdef DEBUG_NV_FLASH
    	printf("NANVmemset ERROR : NAFlashWrite failed errno: %d \n",result);
    #endif
            break;
        }
        else
        {
            bytesWritten += bytesToWrite;
        }
    }

    if (result != NAFLASH_SUCCESS)
    {
		result = result;
#ifdef DEBUG_NV_FLASH
	printf("NANVmemset ERROR : NAFlashWrite failed errno: %d \n",result);
#endif
    }


}

/*
 *
 *  Function: int NANVBackupWrite (unsigned long offset, char *buffer, unsigned long length)
 *
 *  Description:
 *
 *  This function calls NANVBackupWrite()
 *
 *  Parameters:
 *
 *      offset          position in NVRAM to start write
 *      buffer          pointer to buffer to write
 *      length          number of bytes to write
 *
 *  Return Values:
 *
 *      0       Success
 *      -1      A bounds error occurred.
 *
 */
int NANVBackupWrite (unsigned long offset, char *buffer, unsigned long length)
{
    int result;

    if((offset + length) > nv_flash_sector_size)
	return -1;
    
	if (nv_flash_inited == 0)
	{
#ifdef DEBUG_NV_FLASH
		printf("NANVBackupWrite ERROR: nv_flash not initialized!\n"
			   "nv_flash_sector=%d, nv_flash_sector_backup=%d\n",
			   nv_flash_sector, nv_flash_sector_backup);
#endif
		return -1;
	}
    
    result = NAFlashWrite( nv_flash_sector_backup, offset, length, buffer,  ERASE_AS_NEEDED);

    if ( result == NAFLASH_SUCCESS)    
	return 0;
    else
    {
#ifdef DEBUG_NV_FLASH
	printf("NANVBackupWrite ERROR : NAFlashWrite failed errno: %d\n",result);
#endif 
	return -1;
    }
}

/*
 *
 *  Function: int NANVBackupRead (unsigned long offset, char *buffer, unsigned long maxlength)
 *
 *  Description:
 *
 *  This function calls NANVBackupRead()
 *
 *  Parameters:
 *
 *      offset          position in NVRAM to start read at
 *      buffer          pointer to buffer to load with data
 *      maxlength       number of bytes to read
 *
 *  Return Values:
 *
 *      -1              Invalid parameters supplied
 *      !-1             number of bytes read.
 *
 */
int NANVBackupRead (unsigned long offset, char *buffer, unsigned long maxlength)
{
    int result;

    if((offset + maxlength)> nv_flash_sector_size )
	return -1;

	if (nv_flash_inited == 0)
	{
#ifdef DEBUG_NV_FLASH
		printf("NANVBackupRead ERROR: nv_flash not initialized!\n"
			   "nv_flash_sector=%d, nv_flash_sector_backup=%d\n",
			   nv_flash_sector, nv_flash_sector_backup);
#endif
		return -1;
	}
    
    result = NAFlashRead( nv_flash_sector_backup, offset, maxlength, buffer);
  
    if ( result == NAFLASH_SUCCESS)    
	return 0;
    else
    {
#ifdef DEBUG_NV_FLASH
	printf("NANVBackupRead ERROR : NAFlashRead failed errno: %d\n",result);
#endif 
	return -1;
    }

}

#endif /*BSP_USE_FLASH_FOR_NVRAM */



















