/*-----------------------------------------------------------------------------
//     $Date: 2004/11/19 20:19:09 $
//     $RCSfile: bootload.c,v $
//-----------------------------------------------------------------------------
//
//     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
//     SOLELY FOR USE 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 FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
//     FOR YOUR 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
//     FOR A PARTICULAR PURPOSE.
//     
//     (c) Copyright 2004 Xilinx, Inc.
//     All rights reserved.
//
//---------------------------------------------------------------------------*/
#include "xio.h"
#include "xgpio_l.h"
#include "xbasic_types.h"
#include "sleep.h"
#include "xstatus.h"
#include "xtft.h"
#include "xtft_l.h"
#include "xsysace_l.h"
#include "xparameters.h"
#include "bootload_graphics.h"
#include "bootload_boot_boxdef.h"
//#include "xilinx_logo_greyongrey_bmp.h"
#include "xromlcd.h"

#define UART_BASEADDR   XPAR_OPB_UART16550_0_BASEADDR
#define UART_CLOCK      XPAR_XUARTNS550_CLOCK_HZ
#define UART_BAUDRATE   9600

#define SYSACE_BASEADDR XPAR_OPB_SYSACE_0_BASEADDR
#define TFT_DEVICE_ID   XPAR_PLB_TFT_CNTLR_REF_0_DEVICE_ID
#define GPIO_0_BASEADDR XPAR_OPB_GPIO_0_BASEADDR

#define STATUS_CHECK(Status) { if (Status != XST_SUCCESS) { return Status; } }

#include <stdio.h>
#include "xuartns550_l.h"

static void LoadProgram(XTft *InstancePtr, Xuint32 num)
  {
  xil_printf ("Rebooting to System ACE Configuration Address %d...\r\n",num);
  XromLCDClear();
  XTft_SetColor(InstancePtr, 0x00ffffff, 0x00000000);

  XSysAce_RegWrite16(SYSACE_BASEADDR + XSA_BMR_OFFSET, XSA_BMR_16BIT_MASK);
  XSysAce_mSetControlReg(SYSACE_BASEADDR, XSA_CR_CFGRESET_MASK);
  XSysAce_mSetControlReg(SYSACE_BASEADDR, (num << XSA_CR_CFGADDR_SHIFT) |
	                                         XSA_CR_FORCECFGADDR_MASK |
					         XSA_CR_CFGMODE_MASK |
					         XSA_CR_CFGSTART_MASK);
  XTft_ClearScreen(InstancePtr);
  while(1);
  }

void DisplayBitMapImage1 (XTft *InstancePtr,
			  Xuint32 pixel_upper_left_corn_start_x,
			  Xuint32 pixel_upper_left_corn_start_y,
			  unsigned long *myBitmap)
  {
  Xuint32 count = 0;
  Xuint32 x, y;
  
  for(y=pixel_upper_left_corn_start_y; y<(pixel_upper_left_corn_start_y+myBitmap[1]); y++) {
    for(x=pixel_upper_left_corn_start_x; x<(pixel_upper_left_corn_start_x+myBitmap[0]); x++) {
      XTft_mSetPixel(*(Xuint32 *)InstancePtr->BaseAddress, x, y, myBitmap[count+4]);
      count++;
      }
    count++;
    }
  }

int main()
  {
  XTft Tft;
  XStatus Status;
  Xuint32 old_gpio_dir;
  Xboolean button_n, button_e, button_s, button_w, button_c;
  Xboolean button_pushed, uart_input_avail;
  Xuint32 CurrentSel = 1, LastSel = 1;
  Xuint32 SelColor;
  Xuint32 y_pos;
  char ch;

  XUartNs550_SetBaud(UART_BASEADDR, UART_CLOCK, UART_BAUDRATE);
  XUartNs550_mSetLineControlReg(UART_BASEADDR, XUN_LCR_8_DATA_BITS);

  /* set gpio bits to be able to read buttons */
  old_gpio_dir = XGpio_mReadReg(GPIO_0_BASEADDR, 0x4);
  XGpio_mSetDataDirection(GPIO_0_BASEADDR, 1, old_gpio_dir | 0x00003E00);

  /* Initialize TFT */
  Status = XTft_Initialize(&Tft, TFT_DEVICE_ID);
  STATUS_CHECK(Status);
  
  /* Initialize TFT and display */
  XTft_SetColor(&Tft, 0x00ffffff, 0x00404040);
  XTft_ClearScreen(&Tft);
  XTft_SetPos(&Tft, 400, 200);
  XTft_WriteColorString(&Tft, "Note: Some demos require", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 215);
  XTft_WriteColorString(&Tft, "use of the serial port. ", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 230);
  XTft_WriteColorString(&Tft, "Connect null modem cable", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 245);
  XTft_WriteColorString(&Tft, "from the ML401 to a host", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 260);
  XTft_WriteColorString(&Tft, "(such as a PC) running  ", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 275);
  XTft_WriteColorString(&Tft, "a serial terminal. Use  ", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 290);
  XTft_WriteColorString(&Tft, "the settings: 9600 Baud ", 0x00FFFFFF, 0x00404040);
  XTft_SetPos(&Tft, 400, 305);
  XTft_WriteColorString(&Tft, "8-N-1, No flow control. ", 0x00FFFFFF, 0x00404040);
  XTft_DrawEmptyBox(&Tft, 390,190,600,320, 0x00FFFFFF, 0x2);

  XTft_WriteColorCenteredString(&Tft, "                                                                           ", 0x00FFFFFF, 0x00006000, 15);
  XTft_WriteColorCenteredString(&Tft, "                                                                           ", 0x00FFFFFF, 0x00006000, 25);
  XTft_WriteColorCenteredString(&Tft, " Welcome to the Xilinx Virtex-4 ML401 Evaluation Platform Bootloader Menu! ", 0x00FFFFFF, 0x00006000, 20);
  XTft_WriteColorCenteredString(&Tft, "Please use the directional buttons to choose a demo", 0x00FFFFFF, 0x00404040, 50);
  XTft_WriteColorCenteredString(&Tft, "Press the center button to start the selected demo", 0x00FFFFFF, 0x00404040, 63);

  XTft_DrawFixedSizeButton(&Tft, BOX_1_X_LEFT, BOX_1_Y_LEFT, BOX_1_X_RIGHT, BOX_1_Y_RIGHT, "1. Virtex-4 Slide Show      ", 29, 0x0000FF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_2_X_LEFT, BOX_2_Y_LEFT, BOX_2_X_RIGHT, BOX_2_Y_RIGHT, "2. Web Server Demo          ", 29, 0x00FFFF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_3_X_LEFT, BOX_3_Y_LEFT, BOX_3_X_RIGHT, BOX_3_Y_RIGHT, "3. DSP48 Demo               ", 29, 0x00FFFF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_4_X_LEFT, BOX_4_Y_LEFT, BOX_4_X_RIGHT, BOX_4_Y_RIGHT, "4. Chipscope Pro Demo       ", 29, 0x00FFFF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_5_X_LEFT, BOX_5_Y_LEFT, BOX_5_X_RIGHT, BOX_5_Y_RIGHT, "5. USB Demo                 ", 29, 0x00FFFF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_6_X_LEFT, BOX_6_Y_LEFT, BOX_6_X_RIGHT, BOX_6_Y_RIGHT, "6. My own ACE file          ", 29, 0x00FFFF00);
  XTft_DrawFixedSizeButton(&Tft, BOX_7_X_LEFT, BOX_7_Y_LEFT, BOX_7_X_RIGHT, BOX_7_Y_RIGHT, "7. Load/Restore Flash Images", 29, 0x00FFFF00);

  /* Place the Xilinx logo on the screen */
  //  DisplayBitMapImage1(&Tft, 439, 419, logo_bitmap);

  /* Print Copy of directions to UART */
  xil_printf ("Welcome to the Xilinx Virtex-4 ML401 Evaluation Platform Bootloader Menu!\r\n\r\n");
  xil_printf ("Please choose a demo by typing in the number of the demo you want to use\r\n\r\n");
  xil_printf ("Or select a demo using the directional buttons and LCD or VGA display\r\n");
  xil_printf ("  (Then press the center button to start the selected demo)\r\n\r\n");
  xil_printf ("1. Virtex-4 Slide Show\r\n");
  xil_printf ("2. Web Server Demo\r\n");
  xil_printf ("3. DSP48 Demo\r\n");
  xil_printf ("4. Chipscope Pro Demo\r\n");
  xil_printf ("5. USB Demo\r\n");
  xil_printf ("6. My own ACE file\r\n");
  xil_printf ("7. Load/Restore Flash Images\r\n");

  /* Clear UART input buffer */
  while (XUartNs550_mGetLineStatusReg(UART_BASEADDR) & 0x1)
    ch = XUartNs550_RecvByte(UART_BASEADDR);

  /* print directions to LCD screen */
  XromLCDOn();
  XromLCDInit();
  XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","1. Slideshow    ");

  while (1)
    {
    /* Get Input Selection */
      do {
	ch=0;
        button_pushed = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) & 0x00003E00);
        uart_input_avail = (XUartNs550_mGetLineStatusReg(UART_BASEADDR) & 0x1);
        if (uart_input_avail)
          ch = XUartNs550_RecvByte(UART_BASEADDR);
      } while (!button_pushed && !(uart_input_avail && (ch > '0') && (ch < '8'))); 

    button_n = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) >> 13) & (0x00000001);
    button_e = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) >> 12) & (0x00000001);
    button_s = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) >> 11) & (0x00000001);
    button_w = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) >> 10) & (0x00000001);
    button_c = (XGpio_mGetDataReg(GPIO_0_BASEADDR, 1) >> 9)  & (0x00000001);

    /* get new selection number */
    LastSel = CurrentSel;

    if (button_n | button_w) CurrentSel--;
    if (button_s | button_e) CurrentSel++;
    if (CurrentSel == 0) CurrentSel = 7;
    if (CurrentSel == 8) CurrentSel = 1;
    if (uart_input_avail && (ch > '0') && (ch < '8'))
      CurrentSel = ch - '0';

    /* Redraw previous selection */
    if (LastSel == 1) XTft_DrawFixedSizeButton(&Tft, BOX_1_X_LEFT, BOX_1_Y_LEFT, BOX_1_X_RIGHT, BOX_1_Y_RIGHT, "1. Virtex-4 Slide Show      ", 29, 0x00FFFF00);
    if (LastSel == 2) XTft_DrawFixedSizeButton(&Tft, BOX_2_X_LEFT, BOX_2_Y_LEFT, BOX_2_X_RIGHT, BOX_2_Y_RIGHT, "2. Web Server Demo          ", 29, 0x00FFFF00);
    if (LastSel == 3) XTft_DrawFixedSizeButton(&Tft, BOX_3_X_LEFT, BOX_3_Y_LEFT, BOX_3_X_RIGHT, BOX_3_Y_RIGHT, "3. DSP48 Demo               ", 29, 0x00FFFF00);
    if (LastSel == 4) XTft_DrawFixedSizeButton(&Tft, BOX_4_X_LEFT, BOX_4_Y_LEFT, BOX_4_X_RIGHT, BOX_4_Y_RIGHT, "4. Chipscope Pro Demo       ", 29, 0x00FFFF00);
    if (LastSel == 5) XTft_DrawFixedSizeButton(&Tft, BOX_5_X_LEFT, BOX_5_Y_LEFT, BOX_5_X_RIGHT, BOX_5_Y_RIGHT, "5. USB Demo                 ", 29, 0x00FFFF00);
    if (LastSel == 6) XTft_DrawFixedSizeButton(&Tft, BOX_6_X_LEFT, BOX_6_Y_LEFT, BOX_6_X_RIGHT, BOX_6_Y_RIGHT, "6. My own ACE file          ", 29, 0x00FFFF00);
    if (LastSel == 7) XTft_DrawFixedSizeButton(&Tft, BOX_7_X_LEFT, BOX_7_Y_LEFT, BOX_7_X_RIGHT, BOX_7_Y_RIGHT, "7. Load/Restore Flash Images", 29, 0x00FFFF00);

    /* Draw new selection in correct color */
    if (button_c || (uart_input_avail && (ch > '0') && (ch < '8'))) SelColor = 0x00FF0000;
      else SelColor = 0x0000FF00;
    if (CurrentSel == 1) XTft_DrawFixedSizeButton(&Tft, BOX_1_X_LEFT, BOX_1_Y_LEFT, BOX_1_X_RIGHT, BOX_1_Y_RIGHT, "1. Virtex-4 Slide Show      ", 29, SelColor);
    if (CurrentSel == 2) XTft_DrawFixedSizeButton(&Tft, BOX_2_X_LEFT, BOX_2_Y_LEFT, BOX_2_X_RIGHT, BOX_2_Y_RIGHT, "2. Web Server Demo          ", 29, SelColor);
    if (CurrentSel == 3) XTft_DrawFixedSizeButton(&Tft, BOX_3_X_LEFT, BOX_3_Y_LEFT, BOX_3_X_RIGHT, BOX_3_Y_RIGHT, "3. DSP48 Demo               ", 29, SelColor);
    if (CurrentSel == 4) XTft_DrawFixedSizeButton(&Tft, BOX_4_X_LEFT, BOX_4_Y_LEFT, BOX_4_X_RIGHT, BOX_4_Y_RIGHT, "4. Chipscope Pro Demo       ", 29, SelColor);
    if (CurrentSel == 5) XTft_DrawFixedSizeButton(&Tft, BOX_5_X_LEFT, BOX_5_Y_LEFT, BOX_5_X_RIGHT, BOX_5_Y_RIGHT, "5. USB Demo                 ", 29, SelColor);
    if (CurrentSel == 6) XTft_DrawFixedSizeButton(&Tft, BOX_6_X_LEFT, BOX_6_Y_LEFT, BOX_6_X_RIGHT, BOX_6_Y_RIGHT, "6. My own ACE file          ", 29, SelColor);
    if (CurrentSel == 7) XTft_DrawFixedSizeButton(&Tft, BOX_7_X_LEFT, BOX_7_Y_LEFT, BOX_7_X_RIGHT, BOX_7_Y_RIGHT, "7. Load/Restore Flash Images", 29, SelColor);

    if (CurrentSel == 1) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","1. Slideshow    ");
    if (CurrentSel == 2) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","2.Web Server    ");
    if (CurrentSel == 3) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","3.DSP48 Demo    ");
    if (CurrentSel == 4) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","4.Chipscope Pro ");
    if (CurrentSel == 5) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","5.USB Demo      ");
    if (CurrentSel == 6) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","6.My ACE File   ");
    if (CurrentSel == 7) XromLCDPrintString ("Choose Demo: \x7f\xa5\x7e","7.Program Flash ");

    /* if center enter button then call LoadProgram */
    if ((button_c) || (uart_input_avail && (ch > '0') && (ch < '8'))) LoadProgram(&Tft, CurrentSel);
    }
  return 0;
  }
