
/*******************************************************************************
 * (c) Copyright 2010 Microsemi Corporation.  All rights reserved.
 *
 * File:control_functions.h
 * File history:
 *      Revision: 1.0 Date: January 7th, 2010
 *
 * Description:
 * Support Functions
 *
 * Author: Corporate Applications Engineering
 *
 */

#ifndef CONTROL_FUNCTIONS_H_
#define CONTROL_FUNCTIONS_H_

#include "enable_disable.h"


/* Wait for user input from UART_0 */
uint8_t WaitForOneKeyEntered()
		{
			uint8_t		User_Input_This_Selection;
			uint8_t		rx_size;
			do	{
				rx_size = MSS_UART_get_rx(&g_mss_uart0, &User_Input_This_Selection,1);
			}
			while(rx_size == 0);
			return User_Input_This_Selection;
}

/* SmartFusion MSS peripherals enable/disable control function */
void peripheral_control(
		uint8_t User_Input_This_Selection,
	    uint32_t Peripheral_Enable,
	    uint32_t Peripheral_Disable
	)
{
	uint32_t i;
	const uint32_t RETAIN_MSS_CONFIG 	= 	0xFFFFFFFF;
			if(User_Input_This_Selection == '1') 	{
			SYSREG->SOFT_RST_CR	&= Peripheral_Enable;
			}
			else if(User_Input_This_Selection == '0') 	{
			SYSREG->SOFT_RST_CR	|= Peripheral_Disable;
			}
			else	{
			SYSREG->SOFT_RST_CR	&= RETAIN_MSS_CONFIG;
		   }
			/* Delay for capacitor charging & discharging */
			for(i=0; i<=10000; i++);
}

/* Analog Block power down or power up control function */
void AnalogPowerDown(uint8_t Analog_Pwr_Selection)
{
	uint32_t i;
	const uint32_t RETAIN_MSS_CONFIG 	= 	0xFFFFFFFF;
			if(Analog_Pwr_Selection == '1') 	{
			ACE->ANA_COMM_CTRL	&= ANALOG_PWRDN;
			}
			else if(Analog_Pwr_Selection == '0') 	{
			ACE->ANA_COMM_CTRL	|= ANALOG_PWRUP;
			}
			else	{
			ACE->ANA_COMM_CTRL	&= RETAIN_MSS_CONFIG;
			}
			/* Delay for capacitor charging & discharging */
			for(i=0; i<=10000; i++);
}

/* ADC power down or power up control function */
void ADCPowerDown(uint8_t ADC_Pwr_Selection)
{
	uint32_t i;
	const uint32_t RETAIN_MSS_CONFIG 	= 	0xFFFFFFFF;
			if(ADC_Pwr_Selection == '1') 	{
			ACE->ANA_COMM_CTRL	|= ALL_ADC_PWRDN;
			}
			else if(ADC_Pwr_Selection == '0') 	{
			ACE->ANA_COMM_CTRL	&= ALL_ADC_PWRUP;
			}
			else	{
			ACE->ANA_COMM_CTRL	&= RETAIN_MSS_CONFIG;
			}
			/* Delay for capacitor charging & discharging */
			for(i=0; i<=10000; i++);
}

void ResetCtrlSetup()
{
			SYSREG->SOFT_RST_CR	|= EXT_RST_ENABLE;
			SYSREG->SOFT_RST_CR	&= FAB_RST_DISABLE;
			SYSREG->SOFT_RST_CR	&= MSS_RST_RELEASE;
}

void VrPsmPulse()
{
			SYSREG->VRPSM_CR	&= VRPSM_LOW;
			SYSREG->VRPSM_CR	&= VRPSM_HIG;
			SYSREG->VRPSM_CR	&= VRPSM_LOW;
}

/* SCB reset control function */
void SCBReset(uint8_t SCB_Rst_Selection)
{
	uint32_t i;
	const uint32_t RETAIN_MSS_CONFIG 	= 	0xFFFFFFFF;
			if(SCB_Rst_Selection == '1') 	{
			ACE->ANA_COMM_CTRL	|= ALL_ACB_RESET;
			}
			else if(SCB_Rst_Selection == '0') 	{
			ACE->ANA_COMM_CTRL	&= ALL_ACB_ACTIVE;
			}
			else	{
			ACE->ANA_COMM_CTRL	&= RETAIN_MSS_CONFIG;
			}
			/* Delay for capacitor charging & discharging */
			for(i=0; i<=10000; i++);
}

void DelayUsingCM3(
	uint32_t TIMER1_LOAD_VALUE
)
{
	uint32_t i;
	for (i=0; i <TIMER1_LOAD_VALUE; i ++) {
		__ASM volatile ("NOP");
	}
}

/* Cortex-M3 sleep instruction */
void PutCM3ToSleep()
{
	__ASM volatile ("WFI");
}

__attribute__((__interrupt__)) void RTC_Match_IRQHandler( void )
{
	/* Clear RTC match interrupt. */
	MSS_RTC_clear_irq();
}

/* Function to get user choice for enabling or disabling SmartFusion peripherals */
int enable_disable_peripherals(uint8_t Verbose)
{
	uint8_t input_selection;

	/* The SOFT_RST_CR register Soft Reset Bits for all MSS Peripherals except MSS_UART_0 */

	MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"Valid Options: 1 & 0. All others are Ignored.\n\r" );
	if (Verbose == 1)
	{
		/* Get user choice for IAP Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"IAP Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, IAP_SR_ENABLE, IAP_SR_DISABLE);

		/* Get user choice for GPIO Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"GPIO Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, GPIO_SR_ENABLE, GPIO_SR_DISABLE);

		/* Get user choice for ACE Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"ACE Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, ACE_SR_ENABLE, ACE_SR_DISABLE);

		/* Get user choice for I2C_1 Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"I2C_1 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, I2C_1_SR_ENABLE, I2C_1_SR_DISABLE);

		/* Get user choice for I2C_0 Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"I2C_0 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, I2C_0_SR_ENABLE, I2C_0_SR_DISABLE);

		/* Get user choice for SPI_1 Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"SPI_1 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, SPI_1_SR_ENABLE, SPI_1_SR_DISABLE);

		/* Get user choice for SPI_0 Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"SPI_0 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, SPI_0_SR_ENABLE, SPI_0_SR_DISABLE);

		/* Get user choice for UART_1 Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"UART_1 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, UART_1_SR_ENABLE, UART_1_SR_DISABLE);

		/* Get user choice for TIMER Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"System Timer Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, TIMER_SR_ENABLE, TIMER_SR_DISABLE);

		/* Get user choice for PDMA Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"PDMA Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, PDMA_SR_ENABLE, PDMA_SR_DISABLE);

		/* Get user choice for MAC Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"MAC Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, MAC_SR_ENABLE, MAC_SR_DISABLE);

		/* Get user choice for External Memory Controller Block */
		MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"EMC Block: Enable(1)/Disable(0)*:		\t?\n\r" );
		input_selection = WaitForOneKeyEntered();
		peripheral_control(input_selection, EMC_SR_ENABLE, EMC_SR_DISABLE);
	}
	else
	{
		/* Disable IAP Block */
		peripheral_control(0, IAP_SR_ENABLE, IAP_SR_DISABLE);

		/* Disable ACE Block */
		peripheral_control(0, ACE_SR_ENABLE, ACE_SR_DISABLE);

		/* Disable I2C_1 Block */
		peripheral_control(0, I2C_1_SR_ENABLE, I2C_1_SR_DISABLE);

		/* Disable I2C_0 Block */
		peripheral_control(0, I2C_0_SR_ENABLE, I2C_0_SR_DISABLE);

		/* Disable SPI_1 Block */
		peripheral_control(0, SPI_1_SR_ENABLE, SPI_1_SR_DISABLE);

		/* Disable SPI_0 Block */
		peripheral_control(0, SPI_0_SR_ENABLE, SPI_0_SR_DISABLE);

		/* Disable UART_1 Block */
		peripheral_control(0, UART_1_SR_ENABLE, UART_1_SR_DISABLE);

		/* Disable TIMER Block */
		peripheral_control(0, TIMER_SR_ENABLE, TIMER_SR_DISABLE);

		/* Disable PDMA Block */
		peripheral_control(0, PDMA_SR_ENABLE, PDMA_SR_DISABLE);

		/* Disable MAC Block */
		peripheral_control(0, MAC_SR_ENABLE, MAC_SR_DISABLE);
	}
	return 0;
}

/* Function to enable or disable memory controllers */
int enable_disable_memorycontrollers(uint8_t Verbose)
{
	uint8_t input_selection;
	if (Verbose == 1)
	{
	/* Get user choice for ESRAM_0 Block */
	MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"ESRAM_0 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
	input_selection = WaitForOneKeyEntered();
	peripheral_control(input_selection, ESRAM_0_SR_ENABLE, ESRAM_0_SR_DISABLE);
	/* Get user choice for ESRAM_1 Block */
	MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"ESRAM_1 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
	input_selection = WaitForOneKeyEntered();
	peripheral_control(input_selection, ESRAM_1_SR_ENABLE, ESRAM_1_SR_DISABLE);
	/* Get user choice for ENVM Block */
	MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"ENVM_1 Block: Enable(1)/Disable(0)*:		\t?\n\r" );
	input_selection = WaitForOneKeyEntered();
	peripheral_control(input_selection, ENVM_SR_ENABLE, ENVM_SR_DISABLE);
	/* Get user choice for EMC Block */
	MSS_UART_polled_tx_string( &g_mss_uart0,(const uint8_t*)"EMC Block: Enable(1)/Disable(0)*:		\t?\n\r" );
	input_selection = WaitForOneKeyEntered();
	peripheral_control(input_selection, EMC_SR_ENABLE, EMC_SR_DISABLE);
	}
	else
	{
		/* Disable ESRAM_0 Block */
		peripheral_control(0, ESRAM_0_SR_ENABLE, ESRAM_0_SR_DISABLE);
		/* Disable ESRAM_1 Block */
		peripheral_control(0, ESRAM_1_SR_ENABLE, ESRAM_1_SR_DISABLE);
		/* Disable ENVM Block */
		peripheral_control(0, ENVM_SR_ENABLE, ENVM_SR_DISABLE);
		/* Disable EMC Block */
		peripheral_control(0, EMC_SR_ENABLE, EMC_SR_DISABLE);
		return 0;
	}
	return 0;
}

/* ADC control */
void ADC_control
(
	uint8_t ADC0_Selection,
	uint8_t ADC1_Selection,
	uint8_t ADC2_Selection
)
{
	uint32_t i;
	const uint32_t RETAIN_MSS_CONFIG 	= 	0xFFFFFFFF;

	if(ADC0_Selection == '1') 	{
	ACE->ADC0_MISC_CTRL	|= ADC_PWRDN;
	}
	else if(ADC0_Selection == '0') 	{
	ACE->ADC0_MISC_CTRL	&= ADC_PWRUP;
	}
	else	{
	ACE->ADC0_MISC_CTRL	&= RETAIN_MSS_CONFIG;
	}

	if(ADC1_Selection == '1') 	{
	ACE->ADC1_MISC_CTRL	|= ADC_PWRDN;
	}
	else if(ADC1_Selection == '0') 	{
	ACE->ADC1_MISC_CTRL	&= ADC_PWRUP;
	}
	else	{
	ACE->ADC1_MISC_CTRL	&= RETAIN_MSS_CONFIG;
	}

	if(ADC2_Selection == '1') 	{
	ACE->ADC2_MISC_CTRL	|= ADC_PWRDN;
	}
	else if(ADC2_Selection == '0') 	{
	ACE->ADC2_MISC_CTRL	&= ADC_PWRUP;
	}
	else	{
	ACE->ADC2_MISC_CTRL	&= RETAIN_MSS_CONFIG;
	}
	/* Delay for capacitor charging & discharging */
	for(i=0; i<=10000; i++);
}


#endif /* CONTROL_FUNCTIONS_H_ */
