#include "xparameters.h"
#include "xbasic_types.h"
#include "xio.h"
#include "xintc_l.h"
#include "xuartlite_l.h"

/* get character, or say, selection from keyboard */
unsigned char buff;

/*
 * Interrupt service routine for the UART
 */
void uart_handler(void *callback)
{
  Xuint32 IsrStatus;
  Xuint8 incoming_character;
  /* Check the ISR status register so we can identify the interrupt source */
  IsrStatus = XIo_In32(XPAR_MYUART_BASEADDR + XUL_STATUS_REG_OFFSET);
  /* disable interrupts */
  microblaze_disable_interrupts();

  if ((IsrStatus & (XUL_SR_RX_FIFO_FULL | XUL_SR_RX_FIFO_VALID_DATA)) != 0)
  {
    incoming_character =
      (Xuint8) XIo_In32( XPAR_MYUART_BASEADDR + XUL_RX_FIFO_OFFSET );
	buff= incoming_character;
  }
  /* Enable interrupts */
  microblaze_enable_interrupts();
}

int main()
{
  int j, k, addr;

  /* Use a 2-character array to store input character(1st bit) and null character(2nd bit) */
  char disp_char[2];
  char last='\0';
  disp_char[1]='\0';

  /* Enable UART interrupts and register uart_handler as the ISR */
  XIntc_RegisterHandler( XPAR_INTC_BASEADDR, XPAR_MYUART_DEVICE_ID,
	 		 (XInterruptHandler)uart_handler, (void *)0);
  XIntc_mEnableIntr( XPAR_INTC_BASEADDR, XPAR_MYUART_INTERRUPT_MASK);
  XIntc_mMasterEnable( XPAR_INTC_BASEADDR );
  XIntc_Out32(XPAR_INTC_BASEADDR + XIN_MER_OFFSET, XIN_INT_MASTER_ENABLE_MASK);
  microblaze_enable_interrupts();
  XUartLite_mEnableIntr(XPAR_MYUART_BASEADDR);


/* USER INTERFACE SCREEN */
   print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
   print("\r\n\tWELCOME TO THE GUITAR EFFECTOR\r\n\n\n");

   print("Select which effect you want to experience:\r\n\n");

   print(" 1 - Clean\r\n");
   print(" 2 - Distortion\r\n");
   print(" 3 - Delay\r\n");
   print(" 4 - Echo\r\n");
   print(" 5 - Flange w/o feedback\r\n");
   print(" 6 - Flange w/ feedback\r\n\n");

   print("Enter a number 1-6: \r\n");


  for(;;)
  {
    /* get character from buffer to display */
      microblaze_disable_interrupts();
      disp_char[0] = buff;
      microblaze_enable_interrupts();

      /* Force the input to be one of the selections */
      if(disp_char[0]=='1' || disp_char[0]=='2'|| disp_char[0]=='3' || disp_char[0]=='4' || disp_char[0]=='5' || disp_char[0]=='6')
	{
          if(disp_char[0]!=last)
	    {
	     	 /* print to minicom */
	     	 print(disp_char);
	     	 print("\r");

		 /* set mux controls based on input, first 3 bits are
		    the mux controls */
	      	 if(disp_char[0]=='1')
	      	  j=0x00000000;

		 if(disp_char[0]=='2')
	     	  j=0x20000000;

		 if(disp_char[0]=='3')
	     	  j=0x80000000;

		 if(disp_char[0]=='4')
	      	  j=0xC0000000;

		 if(disp_char[0]=='5')
	      	  j=0xA0000000;

		 if(disp_char[0]=='6')
	      	  j=0xE0000000;

	    	 addr = 0xFEFF1001;
	    	 XIo_Out32(addr, j);

	    	 k = XIo_In32(addr);
	     	print("\r");
	    }
	 }
/* make sure that if user enters selects same effect as current effect nothing happens */
  last=disp_char[0];
  }
 return 0;
}
