/*******************************************************************************
*
*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
*     SOLELY forUSE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
*     XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
*     AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
*     OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
*     IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
*     AND YOU ARE RESPONSIBLE forOBTAINING ANY RIGHTS YOU MAY REQUIRE
*     forYOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
*     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
*     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
*     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
*     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*     forA PARTICULAR PURPOSE.
*     
*     (c) Copyright 2004 Xilinx, Inc.
*     All rights reserved.
*
******************************************************************************/

#include <stdio.h>
#include "globaltypes.h"
#include "xrom_led.h"
#include "xgpio_l.h"
#include "xparameters.h"
#include "sleep.h"
#include "xrom_push_button.h"

#define GPIO_0_BASEADDR XPAR_OPB_GPIO_0_BASEADDR
#define CPU_RESET_BASEADDR 0x90000008

/*
#define N_SW 0x00002000
#define E_SW 0x00001000
#define S_SW 0x00000800
#define W_SW 0x00000400
#define C_SW 0x00000200
*/

/*
At: 0x9000000c:
  bit [7] must be set to 1 for GPIO PS/s.
  bit [8] mouse clk, tristate
  bit [9] mouse data, tristate
  bit [10] keyb clk, tristate
  bit [11] keyb data, tristate
  bit [12] must be set to 1 fo GPIO cpu reset button

At: 0x90000008:
  bit [8] mouse clk, data
  bit [9] mouse data, data
  bit [10] keyb clk, data
  bit [11] keyb data, data
  bit [12] = 1 if cpu reset button is pressed
*/

void XromPBsInit(){
	XGpio_mSetDataDirection(GPIO_0_BASEADDR, 1, 0x00003E00);
}

int XromCheckButton(unsigned long button){
	unsigned long dataRead;

	dataRead = XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) & 0x00003E00;

	if(dataRead == button) return 1;
	else return 0;
}

void XromPBAutoTest(){
	
	int i;
	unsigned long lights, dataRead, cpuData;
	bool NB, SB, EB, WB, CB, CPU_RST;

	NB = SB = EB = WB = CB = CPU_RST = false;

	//SETS CPU RESET BUTTON FOR GPIO
	XGpio_mSetDataDirection(CPU_RESET_BASEADDR, 1, 0x00001000);
	
	xil_printf("Press Each Push Button And CPU Reset Button\r\n");
	xil_printf("If you do not press each button, test will fail in 30 seconds\r\n\r\n");

	lights = 0x00000000;

	for(i=0;i<30000000;i++){

		dataRead = XGpio_mGetDataReg(GPIO_0_BASEADDR, 1);
	    dataRead = dataRead & 0x00003E00;  // Clear out "unused" bits

		switch (dataRead)
     	{
      	case N_SW:
	        NB = true;
			lights = lights | (dataRead >> 5);
        	break;
      	case E_SW:
			EB = true;
	        lights = lights | (dataRead >> 5);
        	break;
      	case S_SW:
			SB = true;
	        lights = lights | (dataRead >> 5);
        	break;
      	case W_SW:
			WB = true;
	        lights = lights | (dataRead >> 5);
        	break;
      	case C_SW:
			CB = true;
	        lights = lights | (dataRead >> 5);
        	break;
		}

		//Check for CPU Reset
		cpuData = XGpio_mGetDataReg(CPU_RESET_BASEADDR, 1);
		cpuData = cpuData & 0x00001000;

		if(cpuData == 0x00001000)
			CPU_RST = true;

		XGpio_mSetDataReg(GPIO_0_BASEADDR, 1, lights);


		if(NB && SB && WB && EB && CB && CPU_RST){
			//add logging
			XromLCDClear();
			XromLCDPrintString("Test Passed");
			xil_printf("Test Passed\r\n\r\n");
			
			XGpio_mSetDataReg(GPIO_0_BASEADDR, 1, 0x0); //turn off LEDs
			return;
		}
		
		usleep(1);
	}

	XromLCDClear();
	XromLCDPrintString("Test Failed");
	xil_printf("Test Failed\r\n\r\n");
	//add logging

}

