/******************** (C) COPYRIGHT 2006 STMicroelectronics ********************
* File Name          : menu.c
* Author             : MCD Application Team
* Date First Issued  : 03/10/2006
* Description        : This file includes the menu navigation driver for the
*                      STR75x-EVAL demonstration.
********************************************************************************
* History:
* 07/17/2006 : V1.0
* 03/10/2006 : V0.1
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private typedef -----------------------------------------------------------*/
  typedef void (* tMenuFunc)(void);
  typedef struct sMenuItem * tMenuItem;
  typedef struct sMenu * tMenu;

/* Private define ------------------------------------------------------------*/

  /* "SEL" key help master LCD graphic */
  u8 SELHelp[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x40, 0x60, 0x70, 0xF8, 0xF8, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0,
  0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x20, 0x20, 0x00, 0x00, 0xE3,
  0x23, 0x20, 0x20, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
  0x80, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x01, 0x01, 0x01, 0x00,
  0x00, 0x00, 0x08, 0x09, 0x09, 0x06, 0x00, 0x00, 0xCF, 0xC9, 0x09, 0x08, 0x00,
  0x00, 0x0F, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x0F, 0x07, 0x03,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x02, 0x06, 0x0E, 0x1F, 0x1F, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  /* "UP" and "DOWN" keys help master LCD graphic */
  u8 UPDOWNHelp[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x40, 0x60, 0x70, 0xF8, 0xF8, 0x70, 0x60, 0x40, 0x00, 0x00, 0x78, 0x80, 0x80,
  0x78, 0x00, 0xF8, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x20, 0x20, 0x00, 0x00, 0xE3,
  0x23, 0x20, 0x20, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x08, 0x09, 0x09, 0x06, 0x00, 0x00, 0xCF, 0xC9, 0x09, 0x08, 0x00,
  0x00, 0x0F, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x11, 0x11, 0x0E, 0x00, 0x0E, 0x11, 0x11,
  0x0E, 0x00, 0x0F, 0x10, 0x0C, 0x10, 0x0F, 0x00, 0x1F, 0x06, 0x0C, 0x1F, 0x00,
  0x00, 0x02, 0x06, 0x0E, 0x1F, 0x1F, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  /* "LEFT" and "RIGHT" keys help master LCD graphic */
  u8 LEFTRIGHTHelp[] = {
  0x00, 0x00, 0x00, 0xF8, 0x80, 0x80, 0x00, 0xF8, 0xA8, 0x88, 0x00, 0xF8, 0x28,
  0x08, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0,
  0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x20, 0x20, 0x00, 0x00, 0xE0,
  0x20, 0x20, 0x20, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
  0x80, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x01, 0x01, 0x01, 0x00,
  0x00, 0x00, 0x08, 0x09, 0x09, 0x06, 0x00, 0x00, 0x0F, 0x09, 0x09, 0x08, 0x00,
  0x00, 0x0F, 0x08, 0x08, 0x88, 0x80, 0x80, 0x01, 0x01, 0x81, 0x0F, 0x07, 0x83,
  0x81, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x0F, 0x02, 0x06, 0x09, 0x00, 0x0F, 0x00, 0x07, 0x08, 0x0A, 0x06, 0x00, 0x0F,
  0x02, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00};

  u8 STLogo30[]= {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7C, 0x7C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
  0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
  0xFE, 0xC1, 0x00, 0x08, 0x3C, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x1C, 0x00,
  0x80, 0xF8, 0xFC, 0xFC, 0xFC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7C,
  0x78, 0x00, 0x01, 0x07, 0xFF, 0x3F, 0x03, 0x80, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07,
  0x01, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00};

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
  extern vu16 PlayIntroDelay;
  u8 MenuItemIndex = 0, nMenuLevel = 0;
  u8 ItemNumb[MAX_MENU_LEVELS];
  u8* CurrentMenu;

  tMenuItem psMenuItem, psCurrentMenuItem;
  tMenu psPrevMenu[MAX_MENU_LEVELS];
  tMenu psCurrentMenu;

  struct sMenuItem
  {
    u8* pszTitle;
    tMenuFunc pfMenuFunc;
    tMenuFunc pfUpDownMenuFunc;
    tMenu psSubMenu ;
  };

  struct sMenu
  {
    u8* pszTitle;
    tMenuItem psItems;
    u8 nItems;
  };


/*------------------------------ Menu level 4 -------------------------------*/
struct sMenuItem TimeShowMenuItems[] = {"     :  :      ", IdleFunc, IdleFunc};
struct sMenu TimeShowMenu = {"    Time Show    ", TimeShowMenuItems, countof(TimeShowMenuItems)};

struct sMenuItem TimeAdjustMenuItems[] = {"    Time Adjust  ", IdleFunc, IdleFunc};
struct sMenu TimeAdjustMenu = {"    Time Adjust  ", TimeAdjustMenuItems, countof(TimeAdjustMenuItems)};

struct sMenuItem DateShowMenuItems[] = {"      /  /       ", IdleFunc, IdleFunc};
struct sMenu DateShowMenu = {"    Date Show    ", DateShowMenuItems, countof(DateShowMenuItems)};

struct sMenuItem DateAdjustMenuItems[] = {"    Date Adjust  ", IdleFunc, IdleFunc};
struct sMenu DateAdjustMenu = {"    Date Adjust  ", DateAdjustMenuItems, countof(DateAdjustMenuItems)};

struct sMenuItem AlarmShowMenuItems[] = {"     :  :        ", IdleFunc, IdleFunc};
struct sMenu AlarmShowMenu = {"    Alarm Show   ", AlarmShowMenuItems, countof(AlarmShowMenuItems)};

struct sMenuItem AlarmAdjustMenuItems[] = {"   Alarm Adjust  ", IdleFunc, IdleFunc};
struct sMenu AlarmAdjustMenu = {"   Alarm Adjust  ", AlarmAdjustMenuItems, countof(AlarmAdjustMenuItems)};


struct sMenuItem StandbyMenu_WAKEUPItems[] = {" Exit: WAKEUP Pin", IdleFunc, IdleFunc};
struct sMenu StandbyMenu_WAKEUP = {"  STANDBY Mode   ", StandbyMenu_WAKEUPItems, countof(StandbyMenu_WAKEUPItems)};

struct sMenuItem STOPMenu_EXTITItems[] = {" Exit: Press KEY ", IdleFunc, IdleFunc};
struct sMenu STOPMenu_EXTIT = {"    STOP Mode    ", STOPMenu_EXTITItems, countof(STOPMenu_EXTITItems)};

struct sMenuItem STOPMenu_RTCItems[] = {"Exit: Alarm/NCKD ", IdleFunc, IdleFunc};
struct sMenu STOPMenu_RTC = {"    STOP Mode    ", STOPMenu_RTCItems, countof(STOPMenu_RTCItems)};

/*------------------------------ Menu level 3 -------------------------------*/
struct sMenuItem SettingDateMenuItems[] = { {"     Adjust      ", Date_Adjust, IdleFunc, &DateAdjustMenu},
                                            {"      Show       ", Date_Show, IdleFunc, &DateShowMenu}};
struct sMenu DateMenu = {"      Date       ", SettingDateMenuItems, countof(SettingDateMenuItems)};

struct sMenuItem SettingTimeMenuItems[] = { {"     Adjust      ", Time_Adjust, IdleFunc, &TimeAdjustMenu},
                                            {"      Show       ", Time_Show, IdleFunc, &TimeShowMenu}};
struct sMenu TimeMenu = {"      Time       ", SettingTimeMenuItems, countof(SettingTimeMenuItems)};

struct sMenuItem SettingAlarmMenuItems[] = { {"     Adjust      ", Alarm_Adjust, IdleFunc, &AlarmAdjustMenu},
                                             {"      Show       ", Alarm_Show, IdleFunc, &AlarmShowMenu}};
struct sMenu AlarmMenu = {"      Alarm      ", SettingAlarmMenuItems, countof(SettingAlarmMenuItems)};


struct sMenuItem RUNMenuItems[] = { {"     60 MHz      ", SetSysClockTo60, SetSysClockTo60},
                                    {"     56 MHz      ", SetSysClockTo56, SetSysClockTo60},
                                    {"     48 MHz      ", SetSysClockTo48, SetSysClockTo60},
                                    {"      4 MHz      ", SetSysClockTo4, SetSysClockTo60}};
struct sMenu RUNMenu = {"    RUN Mode     ", RUNMenuItems, countof(RUNMenuItems)};

struct sMenuItem STOPMenuItems[] = {{"Exit: EXTIT/NCKD ", EnterSTOPMode_EXTIT, IdleFunc, &STOPMenu_EXTIT},
                                    {"Exit: Alarm/NCKD ", EnterSTOPMode_RTCAlarm, IdleFunc, &STOPMenu_RTC}};
struct sMenu STOPMenu = {"    STOP Mode    ", STOPMenuItems, countof(STOPMenuItems)};

struct sMenuItem StandbyMenuItems[] = {{" Exit: RTC Alarm ", EnterSTANDBYMode_RTCAlarm, IdleFunc},
                                       {" Exit: WAKEUP Pin", EnterSTANDBYMode_WAKEUP, IdleFunc, &StandbyMenu_WAKEUP}};
struct sMenu StandbyMenu = {"  STANDBY Mode   ", StandbyMenuItems, countof(StandbyMenuItems)};


struct sMenuItem OSIRISPlayStopMenuItems[] = {{"      Play       ", WavePlayer_Start, IdleFunc},
                                             {"      Stop       ", WavePlayer_Stop, IdleFunc},
                                             {"    Properties   ", WavePlayer_WaveProperties, IdleFunc}};
struct sMenu OSIRISPlayStopMenu = {"     OSIRIS      ", OSIRISPlayStopMenuItems, countof(OSIRISPlayStopMenuItems)};


struct sMenuItem PromoPlayStopMenuItems[] = {{"      Play       ", WavePlayer_Start, IdleFunc},
                                             {"      Stop       ", WavePlayer_Stop, IdleFunc},
                                             {"    Properties   ", WavePlayer_WaveProperties, IdleFunc}};
struct sMenu PromoPlayStopMenu = {"Promotion Speech ", PromoPlayStopMenuItems, countof(PromoPlayStopMenuItems)};

struct sMenuItem RecordedPlayStopMenuItems[] = {{"      Play       ", WavePlayer_Start, IdleFunc},
                                                {"      Stop       ", WavePlayer_Stop, IdleFunc}};
struct sMenu RecordedPlayStopMenu = {"  Recorded wave  ", RecordedPlayStopMenuItems, countof(RecordedPlayStopMenuItems)};


struct sMenuItem StartTestItems[] = {"", BoardSelfTest, IdleFunc};
struct sMenu StartTestMenu = {"", StartTestItems, countof(StartTestItems)};

struct sMenuItem TestReportItems[] = {"", TestReport, IdleFunc};
struct sMenu TestReportMenu = {"", TestReportItems, countof(TestReportItems)};

/*------------------------------ Menu level 2 -------------------------------*/
struct sMenuItem CalendarMenuItems[] = { {"      Time       ", IdleFunc, IdleFunc, &TimeMenu},
                                         {"      Date       ", IdleFunc, IdleFunc, &DateMenu},
                                         {"      Alarm      ", IdleFunc, IdleFunc, &AlarmMenu}};
struct sMenu CalendarMenu = {"     Calendar    ", CalendarMenuItems, countof(CalendarMenuItems)};

struct sMenuItem LowPowerMenuItems[] = {{"      RUN        ", IdleFunc, IdleFunc, &RUNMenu},
                                        {"      STOP       ", IdleFunc, IdleFunc, &STOPMenu},
                                        {"     STANDBY     ", IdleFunc, IdleFunc, &StandbyMenu}};
struct sMenu LowPowerMenu = {"   Low pw modes  ", LowPowerMenuItems, countof(LowPowerMenuItems)};

struct sMenuItem VoiceRecorderMenuItems[] = {" Voice REC Start ", VoiceRec_SMIErase, KeyButtonOff};
struct sMenu VoiceRecorderMenu = {" Voice Recorder  ", VoiceRecorderMenuItems, countof(VoiceRecorderMenuItems)};

struct sMenuItem WavePlayerMenuItems[] = {{"Promotion Speech ", WavePlayer_GlobalVarSetPromo, IdleFunc, &PromoPlayStopMenu},
                                          {"     OSIRIS      ", WavePlayer_GlobalVarSetOSIRIS, IdleFunc, &OSIRISPlayStopMenu},
                                          {"  Recorded wave  ", WavePlayer_GlobalVarReset, IdleFunc, &RecordedPlayStopMenu}};
struct sMenu WavePlayerMenu = {"   Wave Player   ", WavePlayerMenuItems, countof(WavePlayerMenuItems)};

struct sMenuItem PeriodMeasureItems[] = {"  Start Acquire  ", PeriodMeasure_Start, IdleFunc};
struct sMenu PeriodMeasureMenu = {"  Period Measure ", PeriodMeasureItems, countof(PeriodMeasureItems)};

struct sMenuItem USBMouseDemoItems[] = {{"      Start      ", JoyStickHID_Start, IdleFunc}};

struct sMenu USBMouseDemoMenu = {" USB Mouse Demo  ", USBMouseDemoItems, countof(USBMouseDemoItems)};

struct sMenuItem BoardSelfTestItems[] = {{"   Start Test    ", BoardSelfTest, IdleFunc, &StartTestMenu},
                                         {"   Test report   ", TestReport, IdleFunc, &TestReportMenu}};
struct sMenu BoardSelfTestMenu = {" Board Self Test ", BoardSelfTestItems, countof(BoardSelfTestItems)};

/*------------------------------ Menu level 1 -------------------------------*/
struct sMenuItem MainMenuItems[] = {
  {"       Help      ", HelpMenu, IdleFunc},
  {"     Calendar    ", IdleFunc, IdleFunc, &CalendarMenu},
  {"  Low Power Mode ", IdleFunc, IdleFunc, &LowPowerMenu},
  {"  Voice Recorder ", VoiceRec_GlobalVarReset, IdleFunc, &VoiceRecorderMenu},
  {"   Wave Player   ", IdleFunc, IdleFunc, &WavePlayerMenu},
  {"  Period Measure ", IdleFunc, IdleFunc, &PeriodMeasureMenu},
  {" USB Mouse Demo  ", IdleFunc, IdleFunc, &USBMouseDemoMenu},
  {" Board Self Test ", IdleFunc, IdleFunc, &BoardSelfTestMenu},
  {"      About      ", AboutMenu, IdleFunc}};
struct sMenu MainMenu = {"    Main menu    ", MainMenuItems, countof(MainMenuItems)};

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : Menu_Init
* Description    : Initializes the navigation menu.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Menu_Init(void)
{
  psCurrentMenu = &MainMenu;
  psPrevMenu[nMenuLevel] = psCurrentMenu;
  psMenuItem = MainMenuItems;
}

/*******************************************************************************
* Function Name  : DisplayMenu
* Description    : Displays the current menu.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void DisplayMenu(void)
{
  LCD_Clear();
  LCD_DisplayString(Line1, psCurrentMenu->pszTitle, WhiteText);
  LCD_DisplayString(Line2, psMenuItem->pszTitle, BlackText);
  CurrentMenu = psCurrentMenu->pszTitle;
}

/*******************************************************************************
* Function Name  : SelFunc
* Description    : This function is executed when "SEL" push-buttton is pressed.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SelFunc(void)
{
  psCurrentMenuItem = psMenuItem;

  if(psMenuItem->psSubMenu != NULL)
  {
   /* Update the current Item by the submenu */
   MenuItemIndex = 0;
   psCurrentMenu = psMenuItem->psSubMenu;
   psMenuItem = &(psCurrentMenu->psItems)[MenuItemIndex];
   DisplayMenu();
   nMenuLevel++;
   psPrevMenu[nMenuLevel] = psCurrentMenu;
  }

  psCurrentMenuItem->pfMenuFunc();
}

/*******************************************************************************
* Function Name  : RightFunc
* Description    : This function is executed when "Right" push-buttton is pressed.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RightFunc(void)
{
  /* Test on the MenuItemIndex value before incrementing it */
  if(MenuItemIndex >= ((psCurrentMenu->nItems)-1))
  {
    MenuItemIndex = 0;
  }
  else
  {
    MenuItemIndex++;
  }

  /* Get the current menu */
  psMenuItem = &(psCurrentMenu->psItems[MenuItemIndex]);

  DisplayMenu();

  ItemNumb[nMenuLevel] = MenuItemIndex;
}

/*******************************************************************************
* Function Name  : LeftFunc
* Description    : This function is executed when "Left" push-buttton is pressed.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void LeftFunc(void)
{
  if(MenuItemIndex > 0)
  {
    MenuItemIndex--;
  }
  else
  {
    MenuItemIndex = psCurrentMenu->nItems - 1;
  }

  psMenuItem = &psCurrentMenu->psItems[MenuItemIndex];
  DisplayMenu();
  ItemNumb[nMenuLevel] = MenuItemIndex;
}

/*******************************************************************************
* Function Name  : UpDownFunc
* Description    : This function is executed when any of "UP"/"Down" push-butttons
*                  is pressed.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void UpDownFunc(void)
{
  psMenuItem->pfUpDownMenuFunc();

  if(nMenuLevel == 0)
  {
    nMenuLevel++;
  }

  psCurrentMenu = psPrevMenu[nMenuLevel-1];
  psMenuItem = &psCurrentMenu->psItems[ItemNumb[nMenuLevel-1]];
  DisplayMenu();
  ItemNumb[nMenuLevel] = 0;
  MenuItemIndex = ItemNumb[nMenuLevel-1];
  nMenuLevel--;
}

/*******************************************************************************
* Function Name  : ReadKey
* Description    : Reads key from demoboard.
* Input          : None
* Output         : None
* Return         : Return RIGHT, LEFT, SEL, UP, DOWN or NOKEY
*******************************************************************************/
u8 ReadKey(void)
{
  /* "RIGHT" key is pressed */
  if(!GPIO_ReadBit(GPIO1, GPIO_Pin_13))
  {
    while(GPIO_ReadBit(GPIO1,GPIO_Pin_13) == Bit_RESET);
    return RIGHT;
  }
  /* "LEFT" key is pressed */
  if(!GPIO_ReadBit(GPIO1, GPIO_Pin_12))
  {
    while(GPIO_ReadBit(GPIO1, GPIO_Pin_12) == Bit_RESET);
    return LEFT;
  }
  /* "SEL" key is pressed */
  if(!GPIO_ReadBit(GPIO0, GPIO_Pin_2))
  {
    while(GPIO_ReadBit(GPIO0, GPIO_Pin_2) == Bit_RESET);
    return SEL;
  }
  /* "UP" key is pressed */
  if(!GPIO_ReadBit(GPIO0, GPIO_Pin_8))
  {
    while(GPIO_ReadBit(GPIO0, GPIO_Pin_8) == Bit_RESET);
    return UP;
  }
  /* "DOWN" key is pressed */
  if(!GPIO_ReadBit(GPIO1, GPIO_Pin_7))
  {
    while(GPIO_ReadBit(GPIO1, GPIO_Pin_7) == Bit_RESET);
    return DOWN;
  }
  /* No key is pressed */
  else
  {
    return NOKEY;
  }
}

/*******************************************************************************
* Function Name  : IdleFunc
* Description    : Idle function.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void IdleFunc(void)
{
  /* Nothing to execute: return */
  return;
}

/*******************************************************************************
* Function Name  : HelpMenu
* Description    : Display the Help menu.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void HelpMenu(void)
{
  u8 MyKey = 0;
  PlayIntroDelay = 20;

  /* To not detect "SEL" twice */
  Delay(0x1FFFFF);
  /* Wait any bushbuttons press */
  while(MyKey == NOKEY)
  {
    /* Clear the LCD screen */
    LCD_Clear();
    /* Display "         Enter to" message */
    LCD_DisplayString(Line1, "         Enter to", BlackText);
    /* Display "         Sub-Menu" message */
    LCD_DisplayString(Line2, "         Sub-Menu", BlackText);
    /* Display SELHelp graphic */
    LCD_DrawMasterGraphic(SELHelp);
    /* Wait 2sec or return if any pushbutton is pressed */
    while(PlayIntroDelay != 0)
    {
      /* If any key is pressed */
      if(ReadKey() != NOKEY)
      {
        /* Display "Help" menu */
        DisplayMenu();
        /* Exit the while loop */
        return;
      }
    }
    /* Reinitialize PlayIntroDelay to 2sec */
    PlayIntroDelay = 20;
    /* Clear the LCD screen */
    LCD_Clear();
    /* Display "         To Exit " message */
    LCD_DisplayString(Line1, "         To Exit ", BlackText);
    /* Display "         Sub-Menu" message */
    LCD_DisplayString(Line2, "         Sub-Menu", BlackText);
    /* Display UPDOWNHelp graphic */
    LCD_DrawMasterGraphic(UPDOWNHelp);
    /* Wait 2sec or return if any pushbutton is pressed */
    while(PlayIntroDelay != 0)
    {
      /* If any key is pressed */
      if(ReadKey() != NOKEY)
      {
        /* Display "Help" menu */
        DisplayMenu();
        /* Exit the while loop */
        return;
      }
    }
    /* Reinitialize PlayIntroDelay to 2sec */
    PlayIntroDelay = 20;

    /* Clear the LCD screen */
    LCD_Clear();
    /* Display "          Scroll " message */
    LCD_DisplayString(Line1, "          Scroll ", BlackText);
    /* Display "         Sub-Menu" message */
    LCD_DisplayString(Line2, "         Sub-Menu", BlackText);
    /* Display LEFTRIGHTHelp graphic */
    LCD_DrawMasterGraphic(LEFTRIGHTHelp);
    /* Wait 2sec or return if any pushbutton is pressed */
    while(PlayIntroDelay != 0)
    {
      /* If any key is pressed */
      if(ReadKey() != NOKEY)
      {
        /* Display "Help" menu */
        DisplayMenu();
        /* Exit the while loop */
        return;
      }
    }
    /* Reinitialize PlayIntroDelay to 2sec */
    PlayIntroDelay = 20;
    /* read the pressed key */
    MyKey = ReadKey();
  }
}

/*******************************************************************************
* Function Name  : AboutMenu
* Description    : Display the About menu.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void AboutMenu(void)
{
  LCD_Clear();

  /* Display ST Logo on 30*32 pixels */
  LCD_DrawMasterGraphic(STLogo30);

  /* Display "STR75x DEMO" menu */
  LCD_DisplayChar(Line1, 35, 'S', BlackText);
  LCD_DisplayChar(Line1, 42, 'T', BlackText);
  LCD_DisplayChar(Line1, 49, 'R', BlackText);
  LCD_DisplayChar(Line1, 56, '7', BlackText);
  LCD_DisplayChar(Line1, 63, '5', BlackText);
  LCD_DisplayChar(Line1, 70, 'x', BlackText);
  LCD_DisplayChar(Line1, 77, ' ', BlackText);
  LCD_DisplayChar(Line1, 84, 'D', BlackText);
  LCD_DisplayChar(Line1, 91, 'E', BlackText);
  LCD_DisplayChar(Line1, 98, 'M', BlackText);
  LCD_DisplayChar(Line1, 105, 'O', BlackText);

  /* Display "Version 1.0" menu */
  LCD_DisplayChar(Line2, 35, 'V', BlackText);
  LCD_DisplayChar(Line2, 42, 'e', BlackText);
  LCD_DisplayChar(Line2, 49, 'r', BlackText);
  LCD_DisplayChar(Line2, 56, 's', BlackText);
  LCD_DisplayChar(Line2, 63, 'i', BlackText);
  LCD_DisplayChar(Line2, 70, 'o', BlackText);
  LCD_DisplayChar(Line2, 77, 'n', BlackText);
  LCD_DisplayChar(Line2, 84, ' ', BlackText);
  LCD_DisplayChar(Line2, 91, '1', BlackText);
  LCD_DisplayChar(Line2, 98, '.', BlackText);
  LCD_DisplayChar(Line2, 105, '0', BlackText);
}

/******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/
