/****************************************************************************
 * Copyright (c) 2011-2012 Texas Instruments Incorporated - http://www.ti.com
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
#include "platform_internal.h"

/* Errno value */
uint32_t platform_errno = 0;
uint32_t platform_init_return_code = 0;


/* Platform Library Version*/
// #if (PLATFORM_VERSTRING_IN)
// #pragma DATA_SECTION(platform_library_version,"platform_lib");
// static char platform_library_version[16] = PLATFORM_LIB_VERSION;
// #endif

/* Information we need to keep around for access */
#pragma DATA_SECTION(platform_mcb,"platform_lib");
static struct platform_mcb_t {
    uint32_t	frequency;
    int32_t  	board_version;
    int32_t		mastercore;
} platform_mcb = {0, 0, 0};

#if (PLATFORM_WRITE_IN)
#pragma DATA_SECTION(write_type,"platform_lib");
static WRITE_info	write_type;
#pragma DATA_SECTION(write_buffer,"platform_lib");
static char			write_buffer[MAX_WRITE_LEN];
#endif


/* This structure holds information about the devices on the platform */
// #if (PLATFORM_NAND_IN)
// #pragma DATA_SECTION(gDeviceNandBBlist,"platform_lib");
// uint8_t gDeviceNandBBlist[BLOCKS_PER_DEVICE];

// #pragma DATA_SECTION(gDeviceNand,"platform_lib");
// PLATFORM_DEVICE_info gDeviceNand = {0x2C,	0xA1,PLATFORM_DEVICE_NAND, 8, BLOCKS_PER_DEVICE, PAGES_PER_BLOCK, BYTES_PER_PAGE, SPARE_BYTES_PER_PAGE, PLATFORM_DEVID_MT29F1G08ABCHC, 5, 0x800, 0, NULL, NULL};
// #endif

// #if (PLATFORM_NOR_IN)
// #pragma DATA_SECTION(gDeviceNor,"platform_lib");
// PLATFORM_DEVICE_info gDeviceNor  = {0, 0, PLATFORM_DEVICE_NOR, 8, SPI_NOR_SECTOR_COUNT, (SPI_NOR_PAGE_COUNT / SPI_NOR_SECTOR_COUNT), SPI_NOR_PAGE_SIZE, 0, PLATFORM_DEVID_NORN25Q032A, 0, 0, 0, NULL, NULL};
// #endif

#if (PLATFORM_EEPROM_IN)
#pragma DATA_SECTION(gDeviceEeprom0,"platform_lib");
PLATFORM_DEVICE_info gDeviceEeprom0 = {PLATFORM_EEPROM_MANUFACTURER_ID,PLATFORM_EEPROM_DEVICE_ID_1,PLATFORM_DEVICE_EEPROM,	8, 1, 1, 65536, 0, PLATFORM_DEVID_EEPROM50, 0, 0, 0, NULL, NULL};
#pragma DATA_SECTION(gDeviceEeprom1,"platform_lib");
PLATFORM_DEVICE_info gDeviceEeprom1 = {PLATFORM_EEPROM_MANUFACTURER_ID,PLATFORM_EEPROM_DEVICE_ID_2,PLATFORM_DEVICE_EEPROM,	8, 1, 1, 65536, 0, PLATFORM_DEVID_EEPROM51, 0, 0, 0, NULL, NULL};
#pragma DATA_SECTION(gDeviceEeprom2,"platform_lib");
PLATFORM_DEVICE_info gDeviceEeprom2 = {PLATFORM_EEPROM_MANUFACTURER_ID,PLATFORM_EEPROM_DEVICE_ID_2,PLATFORM_DEVICE_EEPROM,  8, 1, 1, 65536, 0, PLATFORM_DEVID_EEPROM57, 0, 0, 0, NULL, NULL};

#endif

/* This structure holds information about the EMAC port on the platform */
#pragma DATA_SECTION(emac_port_mode,"platform_lib");
PLATFORM_EMAC_PORT_MODE emac_port_mode[PLATFORM_MAX_EMAC_PORT_NUM] =
{
    PLATFORM_EMAC_PORT_MODE_PHY
};

#if (PLATFORM_EXTMEMTEST_IN || PLATFORM_INTMEMTEST_IN)
static inline int32_t platform_memory_test (uint32_t start_address, uint32_t end_address);
#endif

/******************************************************************************
 * platform_get_frequency
 *
 * Internal function to read frequency from PLL.
 *
 ******************************************************************************/
static inline uint32_t platform_get_frequency(void)
{
    CSL_Status      status;
    PllcHwSetup     hwSetupRead;
    uint32_t        dsp_freq;
    
    status = CorePllcGetHwSetup (&hwSetupRead);

    if (status != CSL_SOK) {
        IFPRINT(platform_write("platform_get_info: Hardware setup parameters reading... Failed.\n"));
        IFPRINT(platform_write("\tReason: Error setting in hardware validation."\
                " [status = 0x%x].\n", status));
        platform_errno = PLATFORM_ERRNO_GENERIC;
        return (uint32_t)-1;
    } else {
        /* Compute the real dsp freq (*100) */
        dsp_freq = (hwSetupRead.pllM + 1)>> 1;
        dsp_freq = (dsp_freq * PLATFORM_BASE_CLK_RATE_MHZ)/(hwSetupRead.preDiv + 1);        
    }

    return (dsp_freq);
    
}


/******************************************************************************
 * platform_init
 ******************************************************************************/
//#if (PLATFORM_INIT_IN)

/* Registers to enable or disable memory ECC for L1, L2 and MSMC memories */
#define L1PEDSTAT	0x01846404
#define L1PEDCMD	0x01846408
#define L1PEDADDR	0x0184640C
#define L2EDSTAT	0x01846004
#define L2EDCMD		0x01846008
#define L2EDADDR	0x0184600C
#define L2EDCPEC	0x01846018
#define L2EDCNEC	0x0184601C
#define L2EDCEN		0x01846030
#define SMCERRAR	0x0BC00008
#define	SMCERRXR	0x0BC0000C
#define SMEDCC		0x0BC00010
#define SMCEA		0x0BC00014
#define SMSECC		0x0BC00018

/*Enable EDC on MSMC*/
/* Note: Once MSMC EDC is enabled, error correction stays enabled until
 * the MSMC is reset
 */

Platform_STATUS platform_init()
{
    CSL_Status              status;
    //PllcHwSetup             *pllc_hwSetup;
    //PllcHwSetup             pllc_hwSetupRead;

    int loop_count;
    /* Start TCSL so its free running */
    CSL_chipWriteTSCL(0);

    for (loop_count = 0; loop_count < 10; loop_count++) 
    {
        platform_errno = 0;

        // Initialize DDR3
        xmc_setup();

        status = DDR3Init();

        if (status != CSL_SOK)
        {
            platform_errno = PLATFORM_ERRNO_GENERIC;
            return ( (Platform_STATUS) Platform_EFAIL);
        }

         // Run DDR3 test
        if (platform_memory_test(PLL_REINIT_DDR3_TEST_START_ADDR,
                PLL_REINIT_DDR3_TEST_END_ADDR) == Platform_EOK)
        {
            break;
        }
    }

    platform_init_return_code = loop_count;

    if (loop_count == 10) {
        platform_errno = PLATFORM_ERRNO_GENERIC;
        return ( (Platform_STATUS) Platform_EFAIL);
    }

     // Save frequency, its needed by  platform_delay 
    if(!platform_mcb.frequency) {
      platform_mcb.frequency = platform_get_frequency();
    }
    PowerUpDomains();

    // Enable Error Correction for memory
    enableL1PEDC();
    enableEDCL2EDCEN();
    enableL2EDC();
    MSMC_enableEDC();

    return Platform_EOK;
}
/*Enable EDC on L1P*/
static int enableL1PEDC ()
{
	unsigned int status = 0;

	*(unsigned int *)(L1PEDCMD) = 0x1;	//Set EN(bit0)=1

	/* Check the status */
	status = *(unsigned int *)(L1PEDSTAT);

	if ((status<<28) == 0x10000000)
		/* Enabled */
		return 1;

	/* Failed */
	return 0;
}

static int MSMC_enableEDC ()
{
	unsigned int status = 0;

	*(unsigned int *)(SMEDCC) &= 0x7FFFFFFF;	//Clear SEN(bit31)=0
	*(unsigned int *)(SMEDCC) |= 0x40000000;	//Set ECM(bit30)=1

	/* Check the status */
	status = *(unsigned int *)(SMEDCC);


	if ((status>>30)==0x1)
		/* Enabled */
		return 1;

	/* Failed */
	return 0;
}

/*Enable all bits in L2EDCEN*/
static int enableEDCL2EDCEN ()
{
	/* Set DL2CEN(bit0),PL2CEN(bit1),DL2SEN(bit2),PL2SEN(bit3),SDMAEN(bit4)=1 */
	*(unsigned int *)(L2EDCEN) |= 0x1F;
	return 1;
}


/******************************************************************************
 * platform_get_coreid
 ******************************************************************************/
#if (PLATFORM_GETCOREID_IN)
uint32_t platform_get_coreid(void)
{
    return (CSL_chipReadDNUM());
}
#endif

/******************************************************************************
 * platform_get_emac_start_evt_id
 ******************************************************************************/
Platform_STATUS platform_get_emac_start_evt_id(void)
{
    return CSL_GEM_MACRXINTN;
}


/******************************************************************************
 * platform_get_phy_addr
 ******************************************************************************/
#if (PLATFORM_GETPHYADDR_IN)
int32_t platform_get_phy_addr(uint32_t port_num)
{
    IFPRINT(platform_write("platform_get_phy_addr called \n"));

    if(port_num == 0)
	return 0x18;
    else
        return -1;
}
#endif

/******************************************************************************
 * platform_phy_link_status
 ******************************************************************************/
#if (PLATFORM_PHYLINKSTATUS_IN)
Platform_STATUS platform_phy_link_status(uint32_t port_num)
{
    return Platform_EOK;
}
#endif

/******************************************************************************
 * platform_uart_write
 ******************************************************************************/
Platform_STATUS platform_uart_write(uint8_t buf)
{
    //UartWriteData(buf);

    return Platform_EOK;
}

/******************************************************************************
 * platform_uart_set_baudrate
 ******************************************************************************/
Platform_STATUS platform_uart_set_baudrate(uint32_t baudrate) {

	// uint16_t brate;

	// IFPRINT(platform_write("platform_uart_set_baudrate(baudrate=%d) called \n", baudrate));

 //    brate = ((Uint16) (PLATFORM_UART_INPUT_CLOCK_RATE/(baudrate * 16)));

	// UartSetBaudRate(brate);

    return Platform_EOK;
}

/******************************************************************************
 * platform_uart_init
 ******************************************************************************/
Platform_STATUS platform_uart_init(void) {

	// IFPRINT(platform_write("platform_uart_init called \n"));

	// UartInit();

	// platform_uart_set_baudrate(115200);

    return Platform_EOK;
}

#endif


/******************************************************************************
 * platform_led
 ******************************************************************************/
#if (PLATFORM_LED_IN)
Platform_STATUS platform_led(uint32_t led_id, PLATFORM_LED_OP operation, LED_CLASS_E led_class)
{
    // IFPRINT(platform_write("platform_led(ledid=%d,operation=%d,class=%d) called \n", led_id, operation, led_class));

    // switch (led_class) {
    //     case PLATFORM_USER_LED_CLASS:
    //         //fpgaControlUserLEDs((FPGA_UserLed)(led_id),(FPGA_LedStatus) operation);
    //         break;
    //     case PLATFORM_SYSTEM_LED_CLASS:
    //     	return ( (Platform_STATUS) Platform_EUNSUPPORTED);
    //     default:
    //         IFPRINT(platform_write("platform_led: Invalid led_id %d\n", led_id));
    //         platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
    //         return ( (Platform_STATUS) Platform_EUNSUPPORTED);
    // }
    return Platform_EOK;
}
#endif

/******************************************************************************
 * platform_delay
 ******************************************************************************/
#if (PLATFORM_DELAY_IN)
Platform_STATUS platform_delay(double usecs)
{
    int32_t delayCount = (int32_t) (usecs * platform_mcb.frequency);
    int32_t start_val  = (int32_t) CSL_chipReadTSCL();

    while (((int32_t)CSL_chipReadTSCL() - start_val) < delayCount);

    return Platform_EOK;
}

void platform_delaycycles(uint32_t cycles)
{
	uint32_t start_val  = CSL_chipReadTSCL();

	while ((CSL_chipReadTSCL() - start_val) < cycles);

    return;
}
#endif

/******************************************************************************
 * platform_memory_test
 ******************************************************************************/
#if (PLATFORM_EXTMEMTEST_IN || PLATFORM_INTMEMTEST_IN)
static int32_t platform_memory_test (uint32_t start_address, uint32_t end_address)
{
    uint32_t index, value;

    /* Write a pattern */
    for (index = start_address; index < end_address; index += 4) {
        *(volatile uint32_t *) index = (uint32_t)index;
    }

    /* Read and check the pattern */
    for (index = start_address; index < end_address; index += 4) {
        	
    	value = *(uint32_t *) index;
    	
        if (value  != index) {
            IFPRINT(platform_write("platform_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
                index, value, *(volatile uint32_t *) index));
            platform_errno = index;
            return (Platform_EFAIL);
        }
    }

    /* Write a pattern for complementary values */
    for (index = start_address; index < end_address; index += 4) {
        *(volatile uint32_t *) index = (uint32_t)~index;
    }

    /* Read and check the pattern */
    for (index = start_address; index < end_address; index += 4) {

    	value = *(uint32_t *) index;

        if (value  != ~index) {
            IFPRINT(platform_write("platform_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
                index, value, *(volatile uint32_t *) index));
            platform_errno = index;
            return (Platform_EFAIL);
        }
    }

    return Platform_EOK;
}
#endif

/******************************************************************************
 * platform_external_memory_test
 ******************************************************************************/
#if (PLATFORM_EXTMEMTEST_IN)
Platform_STATUS platform_external_memory_test(uint32_t start_address, uint32_t end_address)
{
	IFPRINT(platform_write("platform_external_memory_test(start=0x%x,end=0x%x) called \n", start_address, end_address));

    if((start_address == 0) && (end_address == 0)) {
        start_address = PLATFORM_DDR3_SDRAM_START;
        end_address   = PLATFORM_DDR3_SDRAM_END - 1;
    }

    if ((start_address < PLATFORM_DDR3_SDRAM_START) ||
        (end_address >  PLATFORM_DDR3_SDRAM_END) ||
        (start_address >= end_address)){
        IFPRINT(platform_write("platform_external_memory_test: Start address (0x%08x) or end address (0x%08x)\n",
            start_address, end_address));
        platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
        return ((Platform_STATUS) Platform_EINVALID);
    }

    return platform_memory_test(start_address, end_address);
}
#endif

/******************************************************************************
 * platform_internal_memory_test
 ******************************************************************************/
#if (PLATFORM_INTMEMTEST_IN)
Platform_STATUS platform_internal_memory_test(uint32_t id)
{
    uint32_t start_address, end_address;
    CSL_PSC_MODSTATE state_prev, state_val;
    CSL_PSC_MDLRST   loc_rst_prev, loc_rst_val;
    uint32_t rstiso_prev_flag;    
    uint32_t module_number = 15;
    int32_t status = Platform_EOK;

	IFPRINT(platform_write("platform_internal_memory_test(core=%d) called \n", id));

    if (platform_get_coreid() == id) {
        IFPRINT(platform_write("platform_internal_memory_test: Can't run the test own core(%d)\n",
            id));
        platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
        return ((Platform_STATUS) Platform_EUNSUPPORTED);
    }

    if (id >= PLATFORM_CORE_COUNT) {
        IFPRINT(platform_write("platform_internal_memory_test: core id should be in range [0..%d]\n",
            PLATFORM_CORE_COUNT - 1));
        platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
        return ((Platform_STATUS) Platform_EINVALID);
    }

    /* For the 6657L */
    if(id == 0)
      module_number = 23;
    else
      module_number = 24;

    /* Preserve the state, local reset and resetiso values */
    state_prev          = CSL_PSC_getModuleNextState(module_number);
    loc_rst_prev        = CSL_PSC_getModuleLocalReset(module_number);
    rstiso_prev_flag    = CSL_PSC_isModuleResetIsolationEnabled(module_number);

    /* Clear the state, local reset and resetiso values */
    state_val           = PSC_MODSTATE_SWRSTDISABLE;
    loc_rst_val         = PSC_MDLRST_ASSERTED;

    CSL_PSC_setModuleNextState(module_number, state_val);
    CSL_PSC_setModuleLocalReset(module_number, loc_rst_val);
    CSL_PSC_disableModuleResetIsolation(module_number);

    /* Test L1P memory region*/
    start_address = PLATFORM_L1P_BASE_ADDRESS | (id << 24);
    end_address   = start_address + PLATFORM_L1P_SIZE;
    if (platform_memory_test(start_address, end_address) != Platform_EOK) {
        status = Platform_EFAIL;
    }

    /* Test L1D memory region*/
    start_address = PLATFORM_L1D_BASE_ADDRESS | (id << 24);
    end_address   = start_address + PLATFORM_L1D_SIZE;
    if (platform_memory_test(start_address, end_address) != Platform_EOK) {
        status = Platform_EFAIL;
    }

    /* Restore the previous state, local reset and resetiso values */
    CSL_PSC_setModuleNextState(module_number, state_prev);
    CSL_PSC_setModuleLocalReset(module_number, loc_rst_prev);
    if (rstiso_prev_flag) {
         CSL_PSC_enableModuleResetIsolation(module_number);
    } else {
         CSL_PSC_disableModuleResetIsolation(module_number);
    }
    
    return status;
}
#endif

/******************************************************************************
 * platform_write  - Printf or echo to UART or both
 ******************************************************************************/
#if (PLATFORM_WRITE_IN)
WRITE_info platform_write_configure (WRITE_info	wtype) {
	WRITE_info original;
	IFPRINT(platform_write("platform_write_configure(write_type=%d) called \n", wtype));
	original = write_type;
	write_type = wtype;
	return original;
}

void platform_write(const char *fmt, ... )
{
    va_list 	arg_ptr;
	uint32_t	i, length;
	
    /* Initial platform_write to temporary buffer.. at least try some sort of sanity check so we don't write all over
     * memory if the print is too large.
     */
    if (strlen(fmt) > MAX_WRITE_LEN) {platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return;}
 
    va_start( arg_ptr, fmt );
    length = vsprintf( (char *)write_buffer, fmt, arg_ptr );
    va_end( arg_ptr );

	if ((write_type == PLATFORM_WRITE_PRINTF) || (write_type == PLATFORM_WRITE_ALL)) {
	    System_printf( "%s", write_buffer );
	}

	if ((write_type == PLATFORM_WRITE_UART) || (write_type == PLATFORM_WRITE_ALL)) {
		/* Log to console port (routine only sends a byte at a time) */
		for (i=0; i < length; i++) {
			if (write_buffer[i] == '\n') {
				(void) platform_uart_write((uint8_t)0x0D);
				(void) platform_uart_write((uint8_t)0x0A);
			}
			else {
				(void) platform_uart_write((uint8_t)write_buffer[i]);
			}
		}
	}

	return;
}
#endif


/******************************************************************************
 * platform_flash_open
 ******************************************************************************/
#if (PLATFORM_NAND_IN) || (PLATFORM_NOR_IN)  || (PLATFORM_EEPROM_IN)
PLATFORM_DEVICE_info *platform_device_open(uint32_t deviceid, uint32_t flags ) {
 
	PLATFORM_DEVICE_info *p_info;

	IFPRINT(platform_write("platform_device_open(deviceid=0x%x,flags=0x%x) called \n", deviceid, flags));

#if (PLATFORM_EEPROM_IN)

	if (deviceid == PLATFORM_DEVID_EEPROM50) {
	    /* Store the open flags */
        gDeviceEeprom0.flags	= flags;
        evmI2CInit();
        p_info = &gDeviceEeprom0;
        p_info->handle	= deviceid;
    	return p_info;
	}

	if (deviceid == PLATFORM_DEVID_EEPROM51) {
	    /* Store the open flags */
        gDeviceEeprom1.flags	= flags;
        evmI2CInit();
        p_info = &gDeviceEeprom1;
        p_info->handle	= deviceid;
    	return p_info;
	}

    if (deviceid == PLATFORM_DEVID_EEPROM57) {
        /* Store the open flags */
        gDeviceEeprom2.flags    = flags;
        evmI2CInit();
        p_info = &gDeviceEeprom2;
        p_info->handle  = deviceid;
        return p_info;
    }

#endif

	platform_errno = PLATFORM_ERRNO_UNSUPPORTED;

	return NULL;
}
#endif

/******************************************************************************
 * platform_flash_close
 ******************************************************************************/
Platform_STATUS platform_device_close(PLATFORM_DEVHANDLE deviceid) {
 
	IFPRINT(platform_write("platform_device_close(handle=0x%x) called \n", deviceid));


	if (deviceid == PLATFORM_DEVID_EEPROM50) {
		gDeviceEeprom0.handle = 0;
		return Platform_EOK;
	}

	if (deviceid == PLATFORM_DEVID_EEPROM51) {
		gDeviceEeprom1.handle = 0;
		return Platform_EOK;
	}

    if (deviceid == PLATFORM_DEVID_EEPROM57) {
        gDeviceEeprom2.handle = 0;
        return Platform_EOK;
    }

	return Platform_EUNSUPPORTED;
}

/******************************************************************************
 * platform_flash_read_spare_data
 ******************************************************************************/
#if (PLATFORM_NAND_IN) || (PLATFORM_NOR_IN) || (PLATFORM_EEPROM_IN)
Platform_STATUS platform_device_read_spare_data(PLATFORM_DEVHANDLE deviceid,
												uint32_t block_number,
												uint32_t page_number,
												uint8_t *buf) {

	IFPRINT(platform_write("platform_device_read_spare_data(handle=0x%x, block=%d, page=%d,buf=0x%x) called \n",
			deviceid, block_number, page_number, buf));

	if (buf == NULL) {
		platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
		return Platform_EINVALID;
	}


	return Platform_EUNSUPPORTED;
													
}
#endif


/******************************************************************************
 * platform_flash_write_spare_data
 ******************************************************************************/
#if (PLATFORM_NAND_IN) || (PLATFORM_NOR_IN) || (PLATFORM_EEPROM_IN)
Platform_STATUS platform_device_write_spare_data(PLATFORM_DEVHANDLE deviceid,
												uint32_t block_number,
												uint32_t page_number,
												uint8_t *buf) {

	IFPRINT(platform_write("platform_device_write_spare_data(handle=0x%x, block=%d, page=%d,buf=0x%x) called \n",
			deviceid, block_number, page_number, buf));

	if (buf == NULL) {
		platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
		return Platform_EINVALID;
	}

	return Platform_EUNSUPPORTED;
													
}
#endif

/******************************************************************************
 * platform_flash_read
 ******************************************************************************/
Platform_STATUS i2c_eeprom_read(PLATFORM_DEVHANDLE 	deviceid,
									 uint32_t 	offset,
                                     uint8_t 	*buf,
                                     uint32_t	len) {

	IFPRINT(platform_write("i2c_eeprom_read(handle=0x%x, offset=%d, len=%d, buf=0x%x) called \n",
			deviceid, offset, len, buf));

	if (buf == NULL || len == 0) {
		platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
		return Platform_EINVALID;
	}

    //if (i2cEepromRead (offset, len, buf, deviceid) != I2C_RET_OK) {
    //    System_printf("platform_eeprom_read: EEPROM read failed \n");
    //    return ( (Platform_STATUS) Platform_EFAIL);
    //}
    if (i2cRead (offset, len, buf, deviceid) != I2C_RET_OK) {
        System_printf("platform_eeprom_read: EEPROM read failed \n");
        return ( (Platform_STATUS) Platform_EFAIL);
    }

    return Platform_EOK;
}


/******************************************************************************
 * platform_flash_write
 ******************************************************************************/
Platform_STATUS i2c_eeprom_write(PLATFORM_DEVHANDLE 	deviceid,
									 uint32_t 	offset,
                                     uint8_t 	*buf,
                                     uint32_t	len) {

	//System_printf("i2c_eeprom_write( handle=0x%x, offset=%d, len=%d, buf=0x%x ) called \n",
	//		deviceid, offset, len, buf);

	/* Check general args */
	if (buf == NULL || len == 0) {
		platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
		return Platform_EINVALID;
	}

	//if( 1 != len )
	//{
	//    if (i2cEepromWriteByteAddr(offset, deviceid, buf, len, I2C_RELEASE_BUS) != I2C_RET_OK) {
	//        System_printf("i2c_eeprom_write: EEPROM write for address 0x%x failed\n", deviceid);
	//        platform_errno = PLATFORM_ERRNO_EEPROM;
	//        return ( (Platform_STATUS) Platform_EFAIL);
	//     }
	//}
	//else
	{
	    if (i2cWrite(offset, deviceid, buf, len, I2C_RELEASE_BUS) != I2C_RET_OK) {
	        //System_printf("i2c_eeprom_write: EEPROM write for address 0x%x failed\n", deviceid);
	        platform_errno = PLATFORM_ERRNO_EEPROM;
	        return ( (Platform_STATUS) Platform_EFAIL);
	     }
	}

   return Platform_EOK;
}
									
/******************************************************************************
 * platform_flash_erase_block
 ******************************************************************************/
#if (PLATFORM_NAND_IN) || (PLATFORM_NOR_IN) || (PLATFORM_EEPROM_IN)
Platform_STATUS platform_device_erase_block(PLATFORM_DEVHANDLE	deviceid,
                                           uint32_t block_number) {

	IFPRINT(platform_write("platform_device_erase_block(handle=0x%x, blockt=%d) called \n",
			deviceid, block_number));


	return Platform_EUNSUPPORTED;
}
#endif
																

//#if PLATFORM_CACHE_IN
//uint32_t Convert_CoreLocal2GlobalAddr (uint32_t  addr)
//{
//    uint32_t coreNum;
//
//    /* Get the core number. */
//#ifdef SIMULATOR_SUPPORT
//    coreNum = CSL_chipReadDNUM();
//#else
//    coreNum = platform_get_coreid();
//#endif
//    /* Check if the address is a valid Local L2 address to convert */
//    if ( (addr >= (uint32_t) 0x800000) &&
//         (addr <  (uint32_t) 0x880000) ) {
//         /* Compute the global address. */
//         return ((1 << 28) | (coreNum << 24) | (addr & 0x00ffffff));
//    }
//    else {
//        return (addr);
//    }
//}
//#endif

/* OSAL functions for Platform Library */
//uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
//{
//    return malloc(num_bytes);
//}

//void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
//{
//    /* Free up the memory */
//    if (dataPtr)
//    {
//        free(dataPtr);
//    }
//}

void Osal_platformSpiCsEnter(void)
{
    /* Get the hardware semaphore.
     *
     * Acquire Multi core CPPI synchronization lock
     */
    //not use
    //while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);

    return;
}

void Osal_platformSpiCsExit (void)
{
    /* Release the hardware semaphore
     *
     * Release multi-core lock.
     */
    //not use
    //CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);

    return;
}

