www.pudn.com > iMx31_WCE600.rar > menu.c
// // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. // If you did not accept the terms of the EULA, you are not authorized to use // this source code. For a copy of the EULA, please see the LICENSE.RTF on your // install media. // //------------------------------------------------------------------------------ // // Copyright (C) 2004-2006, 2007 Freescale Semiconductor, Inc. All Rights Reserved. // THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS // AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT // //------------------------------------------------------------------------------ // // File: menu.c // // Menu routines for the bootloader. // //------------------------------------------------------------------------------ #include#include "loader.h" //----------------------------------------------------------------------------- // External Functions extern void ResetDefaultBootCFG(BOOT_CFG *pBootCFG); extern BOOL StoreBootCFG(BOOT_CFG *BootCFG); extern BOOL NANDFormatNK(void); extern BOOL NANDFormatAll(void); extern void SetMAC(BOOT_CFG *pBootCFG); extern void CvtMAC(USHORT MacAddr [ 3 ], char * pszDottedD); extern void SetBootMe(BOOT_CFG *pBootCFG); extern void SetDelay(BOOT_CFG *pBootCFG); //----------------------------------------------------------------------------- // External Variables extern BSP_ARGS *g_pBSPArgs; extern BOOT_CFG g_BootCFG; extern BOOL g_DownloadImage; //----------------------------------------------------------------------------- // Defines //----------------------------------------------------------------------------- // Types //----------------------------------------------------------------------------- // Global Variables //----------------------------------------------------------------------------- // Local Variables //------------------------------------------------------------------------------ // Local Functions // static void SetUARTChannel(BOOT_CFG *pBootCFG); //------------------------------------------------------------------------------ // // Function: BLMenu // // Provides boot loader menu interface. // // Parameters: // None. // // Returns: // TRUE indicates success. FALSE indicates failure. // //------------------------------------------------------------------------------ BOOL BLMenu() { UINT32 AutoBootDelay = 0; BOOLEAN bCFGChanged = FALSE; UINT32 StartTime, CurrTime, PrevTime; UINT32 Selection; UCHAR chStr[20] = "\0"; // If mac address has not been programmed, immediately drop into menu // so user can give us one. The ADS EEPROM connected to the CS8900A // does not contain the proper values to allow the MAC to be obtained // automatically. if (!g_BootCFG.mac[0] && !g_BootCFG.mac[1] && !g_BootCFG.mac[2]) { EdbgOutputDebugString("WARNING: Uninitialized MAC address. Select valid address using menu.\r\n"); Selection = 0x20; } else { AutoBootDelay = g_BootCFG.delay; switch(g_BootCFG.autoDownloadImage) { case BOOT_CFG_AUTODOWNLOAD_NK_NOR: g_DownloadImage = FALSE; EdbgOutputDebugString("\r\nPress [ENTER] to launch image stored in NOR flash or [SPACE] to cancel.\r\n"); EdbgOutputDebugString("\r\nInitiating image launch in %d seconds. ", AutoBootDelay--); break; case BOOT_CFG_AUTODOWNLOAD_NK_NAND: g_DownloadImage = FALSE; EdbgOutputDebugString("\r\nPress [ENTER] to launch image stored in NAND flash or [SPACE] to cancel.\r\n"); EdbgOutputDebugString("\r\nInitiating image launch in %d seconds. ", AutoBootDelay--); break; case BOOT_CFG_AUTODOWNLOAD_IPL_NAND: g_DownloadImage = FALSE; EdbgOutputDebugString("\r\nPress [ENTER] to launch IPL stored in NAND flash or [SPACE] to cancel.\r\n"); EdbgOutputDebugString("\r\nInitiating IPL launch in %d seconds. ", AutoBootDelay--); break; default: g_DownloadImage = TRUE; EdbgOutputDebugString("\r\nPress [ENTER] to download now or [SPACE] to cancel.\r\n"); EdbgOutputDebugString("\r\nInitiating image download in %d seconds. ", AutoBootDelay--); break; } // Get a snapshot of the RTC seconds count. // StartTime = OEMEthGetSecs(); PrevTime = StartTime; CurrTime = StartTime; Selection = (UINT32)OEM_DEBUG_READ_NODATA; // Allow the user an amount of time to halt the auto boot/download process. // Count down to 0 before proceeding with default operation. // while ((CurrTime - StartTime) < g_BootCFG.delay) { UINT8 i=0; UINT8 j; Selection = OEMReadDebugByte(); if ((Selection == 0x20) || (Selection == 0x0d)) { break; } CurrTime = OEMEthGetSecs(); if (CurrTime > PrevTime) { PrevTime = CurrTime; if (AutoBootDelay < 9) i = 11; else if (AutoBootDelay < 99) i = 12; else if (AutoBootDelay < 999) i = 13; for (j = 0; j < i; j++) { OEMWriteDebugByte((BYTE)0x08); // print back space } KITLOutputDebugString ( "%d seconds. ", AutoBootDelay--); } } } switch (Selection) { case OEM_DEBUG_READ_NODATA: // fall through if nothing typed case 0x0d: // user canceled wait { if (g_BootCFG.autoDownloadImage) { KITLOutputDebugString ( "\r\nLaunching flash image ... \r\n"); } else { KITLOutputDebugString ( "\r\nStarting auto download ... \r\n"); } break; } case 0x20: { Selection = 0; for (;;) { // Show menu KITLOutputDebugString ( "\r\n\r\nBoot Loader Configuration%s:\r\n\r\n", bCFGChanged ? " (UNSAVED CHANGES)" : ""); PREFAST_SUPPRESS(5425, "Suppressed since it requires coredll.lib which increases the image drastically"); _ltoa(g_BootCFG.Channel,(CHAR *)chStr,10); KITLOutputDebugString ( "0) UART Channel: %s\r\n",chStr); switch(g_BootCFG.BaudRate) { case SBOOT_BAUDRATE_9600: KITLOutputDebugString("1) BaudRate: 9600\r\n"); break; case SBOOT_BAUDRATE_19200: KITLOutputDebugString("1) BaudRate: 19200\r\n"); break; case SBOOT_BAUDRATE_38400: KITLOutputDebugString("1) BaudRate: 38400\r\n"); break; case SBOOT_BAUDRATE_57600: KITLOutputDebugString("1) BaudRate: 57600\r\n"); break; default: KITLOutputDebugString("1) BaudRate: 115200\r\n"); break; } switch(g_BootCFG.Parity) { case SBOOT_PARITY_EVEN: KITLOutputDebugString("2) Parity: Even\r\n"); break; case SBOOT_PARITY_ODD: KITLOutputDebugString("2) Parity: Odd\r\n"); break; default: KITLOutputDebugString("2) Parity: None\r\n"); break; } switch(g_BootCFG.DataBits) { case SBOOT_DATABITS_7: KITLOutputDebugString("3) Data Bits: 7\r\n"); break; default: KITLOutputDebugString("3) Data Bits: 8\r\n"); break; } switch(g_BootCFG.StopBit) { case SBOOT_STOPBITS_2: KITLOutputDebugString("4) Stop Bit: 2\r\n"); break; default: KITLOutputDebugString("4) Stop Bit: 1\r\n"); break; } switch(g_BootCFG.FlowCtrl) { case SBOOT_FLOWCTRL_ON: KITLOutputDebugString("5) Flow Control: ON\r\n"); break; case SBOOT_FLOWCTRL_OFF: default: KITLOutputDebugString("5) Flow Control: OFF\r\n"); break; } KITLOutputDebugString ( "6) Boot delay: %d seconds\r\n", g_BootCFG.delay); switch(g_BootCFG.autoDownloadImage) { case BOOT_CFG_AUTODOWNLOAD_NK_NOR: KITLOutputDebugString("7) Autoboot: NK from NOR\r\n"); break; case BOOT_CFG_AUTODOWNLOAD_NK_NAND: KITLOutputDebugString("7) Autoboot: NK from NAND\r\n"); break; case BOOT_CFG_AUTODOWNLOAD_IPL_NAND: KITLOutputDebugString("7) Autoboot: IPL from NAND\r\n"); break; default: KITLOutputDebugString("7) Autoboot: Disabled\r\n"); break; } KITLOutputDebugString ( "8) Reset to factory default configuration\r\n"); KITLOutputDebugString ( "9) MAC address: %x-%x-%x-%x-%x-%x\r\n", g_BootCFG.mac[0] & 0x00FF, g_BootCFG.mac[0] >> 8, g_BootCFG.mac[1] & 0x00FF, g_BootCFG.mac[1] >> 8, g_BootCFG.mac[2] & 0x00FF, g_BootCFG.mac[2] >> 8); KITLOutputDebugString ( "10) Format OS NAND region.\r\n"); KITLOutputDebugString ( "11) Format ALL NAND regions.\r\n"); KITLOutputDebugString ( "S) Save configuration\r\n"); KITLOutputDebugString ( "D) Download image now\r\n"); KITLOutputDebugString ( "L) Launch existing flash resident image now\r\n"); KITLOutputDebugString ( "\r\n\r\nEnter your selection: "); // Read user selection Selection = 0; while (! ( ( (Selection >= '0') && (Selection <= '11') ) || ( (Selection == 'D') || (Selection == 'd') ) || ( (Selection == 'L') || (Selection == 'l') ) || ( (Selection == 'S') || (Selection == 's') ) )) { Selection = OEMReadDebugByte(); } KITLOutputDebugString ( "%c\r\n", Selection); // Process user selection switch (Selection) { case '0': SetUARTChannel(&g_BootCFG); bCFGChanged=TRUE; break; case '1': switch(g_BootCFG.BaudRate) { case SBOOT_BAUDRATE_115200: g_BootCFG.BaudRate = SBOOT_BAUDRATE_9600; break; case SBOOT_BAUDRATE_9600: g_BootCFG.BaudRate = SBOOT_BAUDRATE_19200; break; case SBOOT_BAUDRATE_19200: g_BootCFG.BaudRate = SBOOT_BAUDRATE_38400; break; case SBOOT_BAUDRATE_38400: g_BootCFG.BaudRate = SBOOT_BAUDRATE_57600; break; default: g_BootCFG.BaudRate = SBOOT_BAUDRATE_115200; break; } bCFGChanged=TRUE; break; case '2': switch(g_BootCFG.Parity) { case SBOOT_PARITY_NONE: g_BootCFG.Parity = SBOOT_PARITY_EVEN; break; case SBOOT_PARITY_EVEN: g_BootCFG.Parity = SBOOT_PARITY_ODD; break; default: g_BootCFG.Parity = SBOOT_PARITY_NONE; break; } bCFGChanged=TRUE; break; case '3': switch(g_BootCFG.DataBits) { case SBOOT_DATABITS_8: g_BootCFG.DataBits = SBOOT_DATABITS_7; break; default: g_BootCFG.DataBits = SBOOT_DATABITS_8; break; } bCFGChanged=TRUE; break; case '4': switch(g_BootCFG.StopBit) { case SBOOT_STOPBITS_1: g_BootCFG.StopBit = SBOOT_STOPBITS_2; break; default: g_BootCFG.StopBit = SBOOT_STOPBITS_1; break; } bCFGChanged=TRUE; break; case '5': switch(g_BootCFG.FlowCtrl) { case SBOOT_FLOWCTRL_OFF: g_BootCFG.FlowCtrl = SBOOT_FLOWCTRL_ON; break; default: g_BootCFG.FlowCtrl = SBOOT_FLOWCTRL_OFF; break; } bCFGChanged=TRUE; break; case '6': SetDelay(&g_BootCFG); bCFGChanged=TRUE; break; case '7': switch(g_BootCFG.autoDownloadImage) { case BOOT_CFG_AUTODOWNLOAD_NONE: g_BootCFG.autoDownloadImage = BOOT_CFG_AUTODOWNLOAD_NK_NOR; break; case BOOT_CFG_AUTODOWNLOAD_NK_NOR: g_BootCFG.autoDownloadImage = BOOT_CFG_AUTODOWNLOAD_NK_NAND; break; case BOOT_CFG_AUTODOWNLOAD_NK_NAND: g_BootCFG.autoDownloadImage = BOOT_CFG_AUTODOWNLOAD_IPL_NAND; break; default: g_BootCFG.autoDownloadImage = BOOT_CFG_AUTODOWNLOAD_NONE; break; } bCFGChanged=TRUE; break; case '8': ResetDefaultBootCFG(&g_BootCFG); break; case '9': SetMAC(&g_BootCFG); bCFGChanged=TRUE; break; case '10': KITLOutputDebugString("\r\nWARNING: Format of OS NAND region requested.\r\n"); KITLOutputDebugString("Do you want to continue (y/n)? "); do { Selection = tolower(OEMReadDebugByte()); } while ((Selection != 'y') && (Selection != 'n')); KITLOutputDebugString("\r\n"); if (Selection == 'y') { NANDFormatNK(); } break; case '11': KITLOutputDebugString("\r\nWARNING: Format of all NAND regions requested.\r\n"); KITLOutputDebugString("Boot loader and boot configuration regions will be erased!!!\r\n"); KITLOutputDebugString("Do you want to continue (y/n)? "); do { Selection = tolower(OEMReadDebugByte()); } while ((Selection != 'y') && (Selection != 'n')); KITLOutputDebugString("\r\n"); if (Selection == 'y') { NANDFormatAll(); } break; case 'D': case 'd': g_DownloadImage = TRUE; goto exitMenu; break; case 'L': case 'l': if (g_BootCFG.autoDownloadImage == BOOT_CFG_AUTODOWNLOAD_NONE) { KITLOutputDebugString("\r\nWARNING: You must select NOR/NAND/SD-MMC using Autoboot menu option.\r\n"); } else { g_DownloadImage = FALSE; goto exitMenu; } break; case 'S': case 's': StoreBootCFG(&g_BootCFG); bCFGChanged=FALSE; break; default: break; } } } } exitMenu: if (bCFGChanged == TRUE) { StoreBootCFG(&g_BootCFG); } // EEPROM on ADS does not have proper contents to allow CS8900 to automatically // read MAC address during initialization. We must provide MAC from the Boot // configuration parameters previously loaded. memcpy(g_pBSPArgs->kitl.mac, g_BootCFG.mac, 6); return(TRUE); } //------------------------------------------------------------------------------ // // Function: SetUARTChannel // // Allows user to select the respective UART channel for serial boot. // // Parameters: // eBootCFG // [out] Points to bootloader configuration that will be updated with // the boot delay entered by the user. // // Returns: // None. // //------------------------------------------------------------------------------ static void SetUARTChannel(BOOT_CFG *pBootCFG) { char szCount[16]; WORD cwNumChars = 0; UINT16 InChar = 0; INT32 dwCharRead = OEM_DEBUG_READ_NODATA; KITLOutputDebugString ( "\r\nEnter UART channel [1-5]: "); while (!((InChar == 0x0d) || (InChar == 0x0a))) { dwCharRead = OEMReadDebugByte(); if (dwCharRead != OEM_DEBUG_COM_ERROR && dwCharRead != OEM_DEBUG_READ_NODATA) { InChar = (UINT16)dwCharRead; // If it's a number or a period, add it to the string if ((InChar >= '0' && InChar <= '9')) { if (cwNumChars < 16) { szCount[cwNumChars++] = (char)InChar; OEMWriteDebugByte((BYTE)InChar); } } // If it's a backspace, back up else if (InChar == 8) { if (cwNumChars > 0) { cwNumChars--; OEMWriteDebugByte((BYTE)InChar); } } } } // If it's a carriage return with an empty string, don't change anything. if (cwNumChars) { szCount[cwNumChars] = '\0'; pBootCFG->Channel = atoi(szCount); if ((pBootCFG->Channel < 1) || (pBootCFG->Channel > 5)) { pBootCFG->Channel = DEFAULT_SBOOT_CHANNEL; } } }