/** \file MAXREFDES14.c ******************************************************
 *
 *             Project: Sonoma (MAXREFDES14#)
 *            Filename: MAXREFDES14.c
 *         Description: This module contains the Main application for the
 *                      AVNET LX9 MicroBoard implementation of the MAXREFDES14
 *                      example program.
 *
 *    Revision History:
 *\n                    05-31-13    Rev 01.00    GL    Initial Release
 * 
 *  --------------------------------------------------------------------
 * 
 *    This code follows the following naming conventions.
 * 
 * 	  char                   chPmodValue
 * 	  char (array)           sPmodString[16]
 * 	  float                  fPmodValue
 * 	  int                    nPmodValue
 * 	  int (array)            anPmodValue[16]
 * 	  u16                    uPmodValue
 * 	  u8                     uchPmodValue
 * 	  u8 (array)             auchPmodBuffer[16]
 * 	  unsigned int           unPmodValue
 * 	  int *                  punPmodValue
 * 
 * ------------------------------------------------------------------------- */
/*
 * Copyright (C) 2012 Maxim Integrated Products, All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Maxim Integrated Products
 * shall not be used except as stated in the Maxim Integrated Products
 * Branding Policy.
 *
 * The mere transfer of this software does not imply any licenses
 * of trade secrets, proprietary technology, copyrights, patents,
 * trademarks, maskwork rights, or any other form of intellectual
 * property whatsoever. Maxim Integrated Products retains all ownership rights.
 *
 ***************************************************************************/
/*!\mainpage Main Page
 *
 * \section intro_sec Introduction
 *
 * This is the code documentation for the Sonoma (MAXREFDES14#) subsystem reference design.
 * \n
 * \n The Files page contains the File List page and the Globals page.
 * \n
 * \n The Globals page contains the Functions, Variables, and Macros sub-pages.
 *
 * \image html MAXREFDES14_Block_Diagram.png "MAXREFDES14# System Block Diagram"
 * \n
 * \image html MAXREFDES14_firmware_Flowchart.png "MAXREFDES14# Firmware Flowchart"
 *
 */

#include <stdio.h>
#include "xparameters.h"
#include "platform.h"
#include "menu.h"
#include "utilities.h"
#include "maximDeviceSpecificUtilities.h"
#include "MAXREFDES14.h"

#define MAJOR_REVISION 01
#define MINOR_REVISION 00

// Globals
XGpio g_xGpioSevenSegment;
unsigned int g_unSevenSegmentValue=0;
char g_sInputString[ INPUT_STRING_MAX_SIZE ];				//This string will hold user input from terminal.
XGpio g_xGpioPmodPortA;
XGpio g_xGpioPmodPortB;

XGpio g_gpButtons;
XGpio g_xGpioLed;
u8 g_PmodPortMuxSettings=0;

int main()
/**
* \brief       Main() function for Analog Essentials example program.
* \par         Details
*              This function sets up and initializes the FPGA and hardware, displays the root menu via
*              Hyperterminal, then dispatches inidividual demo programs for specific module based on
*              user's keypress selection.
*
* \param       None
*
* \retval      Always TRUE
*/
{
	// Variables for the main() function
	u8 uchInput=0;
	u8 uchReadWriteOption=0;
	int nMenuState=0;
	char sRegInfo[3];
	u8 uchCount=0;
	u8 uchRegAddr;
	u32 uchRegValue;
	XUartLite Uart;

	// Xilinx provided utility to initialize the hardware/firmware drivers and enable/disable cache
	init_platform();

	// Clear the Hyperterminal screen by sending printf("\033[2J");
	menu_cls();

	// Initialize the USB UART on the NEXYS-3 board (used to communicate with Hyperterminal)
	XUartLite_Initialize(&Uart,DEFAULT_HYPERTERMINAL_UART_ID);
	XUartLite_ResetFifos(&Uart);
	delay(100);

	// Toggle the LEDs so that the user knows the board is awake
	XGpio_Initialize(&g_xGpioLed, XPAR_LEDS_4BITS_DEVICE_ID);
	XGpio_SetDataDirection(&g_xGpioLed, 1, 0x00000000);	// Set the LED peripheral to outputs
	led_knight_rider(&g_xGpioLed,2);

	// Initialize the GPIO connected to PMOD Ports A..D
	XGpio_Initialize(&g_xGpioPmodPortA, XPAR_AXI_GPIO_0_DEVICE_ID);
	XGpio_Initialize(&g_xGpioPmodPortB, XPAR_AXI_GPIO_1_DEVICE_ID);
	XGpio_SetDataDirection(&g_xGpioPmodPortA, 1, 0x00000000);	// Set the GPIO1 to all be outputs
	XGpio_SetDataDirection(&g_xGpioPmodPortB, 1, 0x00000000);	// Set the GPIO1 to all be outputs

	// Configure the PMOD Port Multiplexers for the default PMOD interfaces (ports a,b,c,d)
	max_configure_PMOD_port(PMOD_PORT_TYPE_SPI,PMOD_PORT_TYPE_SPI,PMOD_PORT_TYPE_GPIO,PMOD_PORT_TYPE_UART);

	// Clear the Screen, and then display the big Maxim banner for about 2 seconds
	menu_cls();
	menu_print_maxim_banner_big();
	printf("Maxim Sonoma (MAXREFDES14#) for the LX9 MicroBoard\r\n");
	printf("Revision v%d.%d\r\n",MAJOR_REVISION,MINOR_REVISION);

	delay(ABOUT_ONE_SECOND * 3);
	//print_seven_segment_number(0.0f);

	/* The main menu loop runs infinitely to display an output similar to the following:
			 *
			 * Press a number to select sampling mode:
			 * {0} Read Registers
			 * {1} Write Registers
			 *
				>>

				The main menu is printed to the screen, and then a blocking call to retrieve a single keypress from the UART is issued.
				The result of that keypress is used to select the read/write mode
	*/
	while(1)
	{
		switch(nMenuState)
		{
			case MAIN_MENU:
				menu_cls();
				menu_print_main_menu();
				do{
					uchReadWriteOption = menu_retrieve_keypress(DEFAULT_HYPERTERMINAL_UART_ADDRESS);

					xil_printf("%c\r\n\n",uchReadWriteOption);
					uchReadWriteOption-=48;
					if(uchReadWriteOption<=1)
					{
							nMenuState = MENU_REG_ADDR;
					}
				}while(uchReadWriteOption>1);
				break;

			case MENU_REG_ADDR:
				xil_printf("Enter the register address in HEX (e.g. 2B)\r\nor press ESC key to go back to the main menu: ");
				uchRegAddr=0;
				uchInput=0;
				for(uchCount=0; ; uchCount++)
				{
					sRegInfo[uchCount] = menu_retrieve_keypress(DEFAULT_HYPERTERMINAL_UART_ADDRESS);
					xil_printf("%c",sRegInfo[uchCount]);
					if(!(sRegInfo[uchCount]!=0x1B && sRegInfo[uchCount]!=0x0D))
							break;
				}
				if(sRegInfo[uchCount]==0x1B)
				{
					sRegInfo[0]=0;
					nMenuState = MAIN_MENU;
					break;
				}
				sRegInfo[uchCount]='\0';
				if(uchReadWriteOption==0)
					nMenuState = MENU_READ_REG;
				else
					nMenuState = MENU_WRITE_REG;
				break;

			case MENU_READ_REG:
				uchRegAddr = htoi(sRegInfo);

				xil_printf("\n%X\r\n\r\n",read_reg(uchRegAddr));

				nMenuState = MENU_REG_ADDR;
				break;


			case MENU_WRITE_REG:
				menu_cls();
				uchRegAddr = htoi(sRegInfo);
				xil_printf("\r\nEnter the register value in HEX (e.g. ABCD12)\r\nor press ESC key to go back to the main menu: ");
				for(uchCount=0; ; uchCount++)
				{
					sRegInfo[uchCount] = menu_retrieve_keypress(DEFAULT_HYPERTERMINAL_UART_ADDRESS);
					xil_printf("%c",sRegInfo[uchCount]);
					if(!(sRegInfo[uchCount]!=0x1B && sRegInfo[uchCount]!=0x0D))
							break;
				}
				if(sRegInfo[uchCount]==0x1B)
				{
					sRegInfo[0]=0;
					nMenuState = MAIN_MENU;
					break;
				}
				sRegInfo[uchCount]='\0';
				uchRegValue = htoi(sRegInfo);
				write_reg(uchRegAddr, uchRegValue);
				xil_printf("\r\nRegister write complete\r\n");
				delay(ABOUT_ONE_SECOND);
				nMenuState = MAIN_MENU;
				break;

			default:
				xil_printf("Invalid Keypress, please try again\r\n");
				delay(ABOUT_ONE_SECOND * 5);
				nMenuState = MAIN_MENU;
				break;
		}
	}

	cleanup_platform();
	return 0;
}
