/***********************************************************************************************
* Company: Actel Corporation
*
* File: main.c
* File history:
*      Revision: 1.0 Date: August 20, 2010
*
* Description:
*
* Program to generate Analog Waveform using Programmable Analog section of
* SmartFusion. The UART_0 is used to give user interface for selection of pattern
* to generate. In this design we are generating 256 samples
* for generating any one of the following five patterns:
*
*	   1.	Constant signal
*	   2.	Positive ramp
*	   3.	Negative ramp
*	   4.	Sinusoidal Waveform
*	   5.	Square Waveform
*
* Cortex-M3 writes the sample value to the DAC0 input register.
* The generated output waveform can be observed on Oscilloscope by probing SDD_0 pin.
*
* Author: Sathish Odiga
*         sathish.odiga@actel.com
*         Corporate Applications Engineering
*
************************************************************************************************/


/**************************************************************************/
/* Standard Includes */
/**************************************************************************/
#include <stdio.h>
#include <string.h>
#include <math.h>

/**************************************************************************/
/* Firmware Includes */
/**************************************************************************/
#include "mss_uart.h"
#include "mss_ace.h"

#define NUM_SAMPLES 0xFF

/* Global variable to store the digital signal samples */
uint8_t lut[NUM_SAMPLES];

/**************************************************************************/
/* Local Function definitions */
/**************************************************************************/

/* Function to insert delay between each sample */
void delay(int i)
{
	int temp = 0;
	while (temp < i)
	temp++;
}

/* Function to read the input character */
char readchar (void)
{
	uint8_t rx_size = 0;
	unsigned char rx_char;
	do {
		rx_size = MSS_UART_get_rx( &g_mss_uart0, &rx_char, sizeof(rx_char) );
		}while ( rx_size == 0);
	return(rx_char);
}

/**************************************************************************/
/* End of Local Function definitions */
/**************************************************************************/

/**************************************************************************/
/* Main Function */
/**************************************************************************/

int main(void)
{
	volatile int i;
	volatile double PI, offset, amplitude, omega, timeperiod, phase;
	volatile char key;

	const uint8_t welcome[] = "\n\r*************Waveform Generation using SMARTFUSION*************\n\r";
	const uint8_t connection[] = "\n\rProbe the SDD_0 output at Mixed Signal Header pin 45 "
								 "using Oscilloscope \n\rand connect probe's ground pin to AGND\n\r";

	const uint8_t pattern[] = "\n\r1-Constant signal"
			                  "\n\r2-Positive ramp"
			                  "\n\r3-Negative ramp"
							  "\n\r4-Sinusoidal waveform"
							  "\n\r5-Square waveform"
							  "\n\r\n\rChoose a pattern (1/2/3/4/5): ";

	const uint8_t instruction[] = "\n\rObserve the output on Oscilloscope";

	/* UART Initialization and Configuration */
	MSS_UART_init
	(
			&g_mss_uart0,
			MSS_UART_57600_BAUD,
			MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT
	);

	MSS_UART_polled_tx( &g_mss_uart0, welcome, sizeof(welcome));
	MSS_UART_polled_tx( &g_mss_uart0, connection, sizeof(connection));

	/* ACE Initialization */
	ACE_init();

	/* Defining DAC0 Configuration */
	ACE_configure_sdd
	(
			SDD0_OUT,
			SDD_8_BITS,
			SDD_VOLTAGE_MODE | SDD_NON_RTZ,
			INDIVIDUAL_UPDATE
	);

	/* Enable SDD_0 */
	ACE_enable_sdd(SDD0_OUT);

	MSS_UART_polled_tx_string(&g_mss_uart0, pattern);
	key = readchar();

	MSS_UART_polled_tx_string(&g_mss_uart0, instruction);

	/* Computation of Waveform Sample values */
	for( i = 0x00; i<=(NUM_SAMPLES); i++)
    {
    	switch(key)
		{
			case('1'):

				/* Constant signal */
				lut[i] = 0x7F;
			break;
			case('2'):

				/* Positive ramp waveform */
				lut[i] = i;
			break;
			case('3'):

				/* Negative ramp waveform */
				lut[i] =255-i;
			break;
			case('4'):

				/* Sinusoidal waveform */
				/* Midpoint if DAC is operating in 8-bit mode */
				offset = 127;
				amplitude = 127;
				PI = 3.1415926358;
				/* This time period has the units "number of DAC updates" */
				timeperiod = 255;
				phase = 0;
				omega = 2*PI/timeperiod;
				lut[i] = offset + amplitude * sin(omega*i + phase);
			break;
			case('5'):

				/* Square waveform */
				if (i < 127)
				{
					lut[i] = 0;
				}
				else
				{
					lut[i] = 0xFF;
				}
			break;
			default:
				/* Constant signal */
				lut[i] = 0x7F;
			break;
		}
    }
	while(1)
	{
		for( i = 0x00; i<=(NUM_SAMPLES); i++)
		{
    	/* set the output of the Sigma-Delta DAC0 */
    	ACE_set_sdd_value(SDD0_OUT, lut[i]);

    	/* Delay to vary the sampling rate */
    	delay (500);
    	}
	}
}


