/** \file MAXREFDES14.c ******************************************************
 *
 *             Project: Sonoma (MAXREFDES14#)
 *            Filename: MAXREFDES14.c
 *         Description: This module contains the Main application for the
 *                      Digilent Zedboard 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:
 *
 *\n    char                    chPmodValue
 *\n    char (array)            sPmodString[16]
 *\n    float                   fPmodValue
 *\n    int                     nPmodValue
 *\n    int (array)             anPmodValue[16]
 *\n    u16                     uPmodValue
 *\n    u16 (array)             auPmodValue[16]
 *\n    u8                      uchPmodValue
 *\n    u8 (array)              auchPmodBuffer[16]
 *\n    unsigned int            unPmodValue
 *\n    int *                   punPmodValue
 *
 *  ------------------------------------------------------------------------- */
/*
 * Copyright (C) 2012 Maxim Integrated Products, Inc., 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 "xparameters.h"	/* EDK generated parameters */
#include "stdio.h"
#include "xil_printf.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
char g_sInputString[ INPUT_STRING_MAX_SIZE ];				//This string will hold user input from terminal.
 XGpio g_xGpioLed;
struct maximOLEDDisplay g_structureOLED;
char g_sTempString[32];

u8 font[1024] = {	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x00, NUL
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x01, SOH
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x02, STX
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x03, ETX
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x03, EOT
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x05, ENQ
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x06, ACK
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x07, BEL
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x08, BS
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x09, HT
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0A, LF
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0B, VT
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0C, FF
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0D, CR
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0E, SO
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x0F, SI
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x10, DLE
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x11, DC1
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x12, DC2
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x13, DC3
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x13, DC4
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x15, NAK
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x16, SYN
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x17, ETB
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x18, CAN
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x19, EM
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1A, SUB
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1B, ESC
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1C, FS
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1D, GS
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1E, RS
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x1F, US
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,		// 0x20, space
		0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,		// 0x21, !
		0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,		// 0x22, "
		0x64,0x3c,0x26,0x64,0x3c,0x26,0x24,0x00,		// 0x23, #
		0x26,0x49,0x49,0x7f,0x49,0x49,0x32,0x00,		// 0x23, $
		0x42,0x25,0x12,0x08,0x24,0x52,0x21,0x00,		// 0x25, %
		0x20,0x50,0x4e,0x55,0x22,0x58,0x28,0x00,		// 0x26, &
		0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,		// 0x27, '
		0x00,0x00,0x1c,0x22,0x41,0x00,0x00,0x00,		// 0x28, (
		0x00,0x00,0x00,0x41,0x22,0x1c,0x00,0x00,		// 0x29, )
		0x00,0x15,0x15,0x0e,0x0e,0x15,0x15,0x00,		// 0x2A, *
		0x00,0x08,0x08,0x3e,0x08,0x08,0x00,0x00,		// 0x2B, +
		0x00,0x00,0x00,0x50,0x30,0x00,0x00,0x00,		// 0x2C, ,
		0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,		// 0x2D, -
		0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,		// 0x2E, .
		0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,		// 0x2F, /
		0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00,		// 0x30, 0
		0x00,0x00,0x41,0x7f,0x40,0x00,0x00,0x00,		// 0x31, 1
		0x00,0x42,0x61,0x51,0x49,0x6e,0x00,0x00,		// 0x32, 2
		0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00,		// 0x33, 3
		0x00,0x18,0x14,0x12,0x7f,0x10,0x00,0x00,		// 0x33, 4
		0x00,0x27,0x49,0x49,0x49,0x71,0x00,0x00,		// 0x35, 5
		0x00,0x3c,0x4a,0x49,0x48,0x70,0x00,0x00,		// 0x36, 6
		0x00,0x43,0x21,0x11,0x0d,0x03,0x00,0x00,		// 0x37, 7
		0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,		// 0x38, 8
		0x00,0x06,0x09,0x49,0x29,0x1e,0x00,0x00,		// 0x39, 9
		0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,		// 0x3A, :
		0x00,0x00,0x00,0x52,0x30,0x00,0x00,0x00,		// 0x3B, //
		0x00,0x00,0x08,0x14,0x14,0x22,0x00,0x00,		// 0x3C, <
		0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00,		// 0x3D, =
		0x00,0x00,0x22,0x14,0x14,0x08,0x00,0x00,		// 0x3E, >
		0x00,0x02,0x01,0x59,0x05,0x02,0x00,0x00,		// 0x3F, ?
		0x3e,0x41,0x5d,0x55,0x4d,0x51,0x2e,0x00,		// 0x40, @
		0x40,0x7c,0x4a,0x09,0x4a,0x7c,0x40,0x00,		// 0x41, A
		0x41,0x7f,0x49,0x49,0x49,0x49,0x36,0x00,		// 0x42, B
		0x1c,0x22,0x41,0x41,0x41,0x41,0x22,0x00,		// 0x43, C
		0x41,0x7f,0x41,0x41,0x41,0x22,0x1c,0x00,		// 0x44, D
		0x41,0x7f,0x49,0x49,0x5d,0x41,0x63,0x00,		// 0x45, E
		0x41,0x7f,0x49,0x09,0x1d,0x01,0x03,0x00,		// 0x46, F
		0x1c,0x22,0x41,0x49,0x49,0x3a,0x08,0x00,		// 0x47, G
		0x41,0x7f,0x08,0x08,0x08,0x7f,0x41,0x00,		// 0x48, H
		0x00,0x41,0x41,0x7F,0x41,0x41,0x00,0x00,		// 0x49, I
		0x30,0x40,0x41,0x41,0x3F,0x01,0x01,0x00,		// 0x4A, J
		0x41,0x7f,0x08,0x0c,0x12,0x61,0x41,0x00,		// 0x4B, K
		0x41,0x7f,0x41,0x40,0x40,0x40,0x60,0x00,		// 0x4C, L
		0x41,0x7f,0x42,0x0c,0x42,0x7f,0x41,0x00,		// 0x4D, M
		0x41,0x7f,0x42,0x0c,0x11,0x7f,0x01,0x00,		// 0x4E, N
		0x1c,0x22,0x41,0x41,0x41,0x22,0x1c,0x00,		// 0x4F, O
		0x41,0x7f,0x49,0x09,0x09,0x09,0x06,0x00,		// 0x50, P
		0x0c,0x12,0x21,0x21,0x61,0x52,0x4c,0x00,		// 0x51, Q
		0x41,0x7f,0x09,0x09,0x19,0x69,0x46,0x00,		// 0x52, R
		0x66,0x49,0x49,0x49,0x49,0x49,0x33,0x00,		// 0x53, S
		0x03,0x01,0x41,0x7f,0x41,0x01,0x03,0x00,		// 0x54, T
		0x01,0x3f,0x41,0x40,0x41,0x3f,0x01,0x00,		// 0x55, U
		0x01,0x0f,0x31,0x40,0x31,0x0f,0x01,0x00,		// 0x56, V
		0x01,0x1f,0x61,0x14,0x61,0x1f,0x01,0x00,		// 0x57, W
		0x41,0x41,0x36,0x08,0x36,0x41,0x41,0x00,		// 0x58, X
		0x01,0x03,0x44,0x78,0x44,0x03,0x01,0x00,		// 0x59, Y
		0x43,0x61,0x51,0x49,0x45,0x43,0x61,0x00,		// 0x5A, Z
		0x00,0x00,0x7f,0x41,0x41,0x00,0x00,0x00,		// 0x5B, [
		0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00,		// 0x5C,
		0x00,0x00,0x41,0x41,0x7f,0x00,0x00,0x00,		// 0x5D, ]
		0x00,0x04,0x02,0x01,0x01,0x02,0x04,0x00,		// 0x5E, ^
		0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00,		// 0x5F, _
		0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,		// 0x60, `
		0x00,0x34,0x4a,0x4a,0x4a,0x3c,0x40,0x00,		// 0x61, a
		0x00,0x41,0x3f,0x48,0x48,0x48,0x30,0x00,		// 0x62. b
		0x00,0x3c,0x42,0x42,0x42,0x24,0x00,0x00,		// 0x63, c
		0x00,0x30,0x48,0x48,0x49,0x3f,0x40,0x00,		// 0x63, d
		0x00,0x3c,0x4a,0x4a,0x4a,0x2c,0x00,0x00,		// 0x65, e
		0x00,0x00,0x48,0x7e,0x49,0x09,0x00,0x00,		// 0x66, f
		0x00,0x26,0x49,0x49,0x49,0x3f,0x01,0x00,		// 0x67, g
		0x41,0x7f,0x48,0x04,0x44,0x78,0x40,0x00,		// 0x68, h
		0x00,0x00,0x44,0x7d,0x40,0x00,0x00,0x00,		// 0x69, i
		0x00,0x00,0x40,0x44,0x3d,0x00,0x00,0x00,		// 0x6A, j
		0x41,0x7f,0x10,0x18,0x24,0x42,0x42,0x00,		// 0x6B, k
		0x00,0x40,0x41,0x7f,0x40,0x40,0x00,0x00,		// 0x6C, l
		0x42,0x7e,0x02,0x7c,0x02,0x7e,0x40,0x00,		// 0x6D, m
		0x42,0x7e,0x44,0x02,0x42,0x7c,0x40,0x00,		// 0x6E, n
		0x00,0x3c,0x42,0x42,0x42,0x3c,0x00,0x00,		// 0x6F, o
		0x00,0x41,0x7f,0x49,0x09,0x09,0x06,0x00,		// 0x70, p
		0x00,0x06,0x09,0x09,0x49,0x7f,0x41,0x00,		// 0x71, q
		0x00,0x42,0x7e,0x44,0x02,0x02,0x04,0x00,		// 0x72, r
		0x00,0x64,0x4a,0x4a,0x4a,0x36,0x00,0x00,		// 0x73, s
		0x00,0x04,0x3f,0x44,0x44,0x20,0x00,0x00,		// 0x73, t
		0x00,0x02,0x3e,0x40,0x40,0x22,0x7e,0x40,		// 0x75, u
		0x02,0x0e,0x32,0x40,0x32,0x0e,0x02,0x00,		// 0x76, v
		0x02,0x1e,0x62,0x18,0x62,0x1e,0x02,0x00,		// 0x77, w
		0x42,0x62,0x14,0x08,0x14,0x62,0x42,0x00,		// 0x78, x
		0x01,0x43,0x45,0x38,0x05,0x03,0x01,0x00,		// 0x79, y
		0x00,0x46,0x62,0x52,0x4a,0x46,0x62,0x00,		// 0x7A, z
		0x00,0x00,0x08,0x36,0x41,0x00,0x00,0x00,		// 0x7B, {
		0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,		// 0x7C, |
		0x00,0x00,0x00,0x41,0x36,0x08,0x00,0x00,		// 0x7D, }
		0x00,0x18,0x08,0x08,0x10,0x10,0x18,0x00,		// 0x7E, ~
		0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55			// 0x7F, DEL
	};


int main(void)
/**
* \brief       Main() function for MAXREFDES14
* \par         Details
*              This function sets up and initializes the FPGA and hardware, displays the menu and sampled data via
*              Hyperterminal (or equivalent Terminal program i.e. Teraterm).
*
* \param       None
*
* \retval      Always TRUE
*/
{
	// Variables for the main() function
	u8 uchReadWriteOption=0;
	char sRegInfo[3];
	u8 uchCount=0;
	u8 uchRegAddr;
	u32 uchRegValue;
	char sTempString[100];
	int nMenuState=0; // Go to Channel Select Menu First

	// 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();

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

	// Initialize the OLED Data structure, the underlying hardware, ...
	// ...and pass a pointer to the active 8x8 pixel font
	initializeOLED(font);

	// Print Welcome Message on OLED
	clearOLEDBuffer(g_structureOLED.writeBuffer);
	sprintf(sTempString,"MAXIM INTEGRATED");
	printfToOLED(0,0,sTempString);
	sprintf(sTempString,"REFERENCE DESIGN");
	printfToOLED(0,1,sTempString);
	sprintf(sTempString,"Revision %02d.%02d\r\n",MAJOR_REVISION,MINOR_REVISION);
	printfToOLED(0,2,sTempString);
	sprintf(sTempString, " ");
	printfToOLED(0,3,sTempString);

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

	delay(ABOUT_ONE_SECOND * 3);

	/* The main menu loop runs infinitely to display an output similar to the following:
		 *
		 * Press a number to select read or write operation:
		 * {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 operation
	*/
	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;
				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;
}
