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; 
        } 
    } 
}