/*******************************************************************************
 *  (c)Copyright 2016-2017 Microsemi Corporation.  All rights reserved.
 *
 *  Configure ZL30364 device.
 *
 * SVN $Revision: $
 * SVN $Date: $
 */

#include "drivers/CoreSPI/core_spi.h"
#include "zl_reg_config.h"
#include "hw_platform.h"
void delay_config(uint32_t div)
{
	volatile uint32_t delay_count = 40000000/div ;/// 128u;

	while(delay_count > 0u)
	{
		--delay_count;
	}
}

spi_instance_t g_flash_core_spi;

#define SPI_SLAVE               0
#define SPI_INSTANCE            &g_flash_core_spi
/*==============================================================================
 * ZL30362 registers are 8-bit registers.
 */
#define ZL_ADDRESS_BITS_MASK    0x0000007Fu
#define ZL_REG_BITS_MASK        0x000000FFu
#define ZL_READY_CODE           0x0000009Fu

#define READ_ZL_READY_REG_CMD   0x00008000u
#define SELECT_ZL_PAGE0_CMD     0x00007F00u

/*==============================================================================
 * Configure the ZL30364 device through its SPI interface.
 */
void configure_zl30364(void)
{
	uint32_t inc;
	uint32_t zl_register = 0;
	uint32_t zl_ready;

	uint8_t read_device_id_cmd[2] = {0x1,0x0};
	/*--------------------------------------------------------------------------
	 * Configure SPI interface.
	 */
	SPI_init( SPI_INSTANCE, CORESPI_BASE_ADDR, 32 );
	SPI_configure_master_mode( SPI_INSTANCE );

	SPI_set_slave_select(SPI_INSTANCE, SPI_SLAVE);

	/*--------------------------------------------------------------------------
	 * Wait for ZL30362 to become ready.
	 * Compare against full ready register value instead of simply polling the
	 * ready bit. This avoids false ready bit detection when the ZL device has
	 * not fully come out of reset and does not respond to SPI transactions yet.
	 * The SPI transfer would typically return all 1's when there is no SPI
	 * device responding to the transaction.
	 */
	read_device_id_cmd[0] = 00;
	read_device_id_cmd[1] = 0x7f;
	SPI_transfer_frame(SPI_INSTANCE, SELECT_ZL_PAGE0_CMD);
	//SPI_transfer_block(SPI_INSTANCE, read_device_id_cmd, 2, 0, 0);
	do {
		zl_register = SPI_transfer_frame(SPI_INSTANCE, READ_ZL_READY_REG_CMD);//READ_ZL_READY_REG_CMD);
		// SPI_transfer_block(SPI_INSTANCE, read_device_id_cmd, 2, read_buffer, sizeof(read_buffer));
		//zl_register = MSS_SPI_transfer_frame(&g_mss_spi1, READ_ZL_READY_REG_CMD);
		zl_ready = zl_register  & ZL_REG_BITS_MASK;
	} while(zl_ready != ZL_READY_CODE);

	/*--------------------------------------------------------------------------
	 * Transfer ZL30362 configuration via SPI.
	 */
	for(inc = 0; inc < sizeof(g_zl30362_config); ++inc)
	{
		uint32_t tx_bits;

		tx_bits = ((inc & ZL_ADDRESS_BITS_MASK) << 8u) | g_zl30362_config[inc];
		SPI_transfer_frame(SPI_INSTANCE, tx_bits);
		if(inc == 0x10)
		{
			delay_config(64);
		} else
		{
			delay_config(1792);
		}
	}
	SPI_clear_slave_select(SPI_INSTANCE, SPI_SLAVE);
}


