📄 maindemo.c
字号:
typedef enum _MENU_CMD
{
MENU_CMD_SERIAL_NUMBER = '1',
MENU_CMD_HOST_NAME,
MENU_CMD_IP_ADDRESS,
MENU_CMD_GATEWAY_ADDRESS,
MENU_CMD_SUBNET_MASK,
MENU_CMD_DNS_ADDRESS,
MENU_CMD_ENABLE_AUTO_CONFIG,
MENU_CMD_DISABLE_AUTO_CONFIG,
MENU_CMD_DOWNLOAD_MPFS,
MENU_CMD_QUIT = '0',
MENU_CMD_INVALID = MENU_CMD_DOWNLOAD_MPFS + 1
} MENU_CMD;
ROM char * const menuCommandPrompt[] =
{
"\r\nNow running application...\r\n",
"\r\nSerial Number (",
"\r\nHost Name (",
"\r\nDefault IP Address (",
"\r\nDefault Gateway Address (",
"\r\nDefault Subnet Mask (",
"\r\nDefault DNS Server Address (",
"\r\nDHCP & IP Gleaning enabled.\r\n",
"\r\nDHCP & IP Gleaning disabled.\r\n",
"\r\nReady to download MPFS image - Use Xmodem protocol.\r\n",
};
ROM char InvalidInputMsg[] = "\r\nInvalid input received - Input ignored.\r\n"
"Press any key to continue...\r\n";
BOOL StringToIPAddress(char *str, IP_ADDR *buffer)
{
BYTE v;
char *temp;
BYTE byteIndex;
temp = str;
byteIndex = 0;
while( v = *str )
{
if ( v == '.' )
{
*str++ = '\0';
buffer->v[byteIndex++] = atoi(temp);
temp = str;
}
else if ( v < '0' || v > '9' )
return FALSE;
str++;
}
buffer->v[byteIndex] = atoi(temp);
return (byteIndex == 3);
}
MENU_CMD GetMenuChoice(void)
{
BYTE c;
while(!DataRdyUART())
{
// Invalidate the EEPROM contents if BUTTON0 is held down for more than 4 seconds
#if defined(MPFS_USE_EEPROM)
if(BUTTON0_IO == 0)
{
TICK StartTime = TickGet();
while(BUTTON0_IO == 0)
{
if(TickGet() - StartTime > 4*TICK_SECOND)
{
XEEBeginWrite(EEPROM_CONTROL, 0x00);
XEEWrite(0x00);
XEEEndWrite();
putrsUART("\r\n\r\nBUTTON0 held for more than 4 seconds. EEPROM contents erased.\r\n\r\n");
break;
}
}
}
#endif
}
c = ReadUART();
if ( c >= '0' && c < MENU_CMD_INVALID )
return c;
else
return MENU_CMD_INVALID;
}
#define MAX_USER_RESPONSE_LEN (20)
void ExecuteMenuChoice(MENU_CMD choice)
{
char response[MAX_USER_RESPONSE_LEN];
IP_ADDR tempIPValue;
IP_ADDR *destIPValue;
putrsUART(CRLF);
putrsUART(menuCommandPrompt[choice-'0']);
switch(choice)
{
case MENU_CMD_SERIAL_NUMBER:
itoa(AppConfig.SerialNumber.Val, response);
putsUART(response);
putrsUART("): ");
if(ReadStringUART(response, sizeof(response)))
{
AppConfig.SerialNumber.Val = atoi(response);
AppConfig.MyMACAddr.v[4] = AppConfig.SerialNumber.v[1];
AppConfig.MyMACAddr.v[5] = AppConfig.SerialNumber.v[0];
}
break;
case MENU_CMD_HOST_NAME:
putsUART(AppConfig.NetBIOSName);
putrsUART("): ");
ReadStringUART(response, sizeof(response) > sizeof(AppConfig.NetBIOSName) ? sizeof(AppConfig.NetBIOSName) : sizeof(response));
if(response[0] != '\0')
{
memcpy(AppConfig.NetBIOSName, (void*)response, sizeof(AppConfig.NetBIOSName));
FormatNetBIOSName(AppConfig.NetBIOSName);
}
break;
case MENU_CMD_IP_ADDRESS:
destIPValue = &AppConfig.MyIPAddr;
goto ReadIPConfig;
case MENU_CMD_GATEWAY_ADDRESS:
destIPValue = &AppConfig.MyGateway;
goto ReadIPConfig;
case MENU_CMD_SUBNET_MASK:
destIPValue = &AppConfig.MyMask;
goto ReadIPConfig;
case MENU_CMD_DNS_ADDRESS:
destIPValue = &AppConfig.PrimaryDNSServer;
ReadIPConfig:
DisplayIPValue(destIPValue);
putrsUART("): ");
ReadStringUART(response, sizeof(response));
if ( !StringToIPAddress(response, &tempIPValue) )
{
putrsUART(InvalidInputMsg);
while(!DataRdyUART());
ReadUART();
}
else
{
destIPValue->Val = tempIPValue.Val;
}
break;
case MENU_CMD_ENABLE_AUTO_CONFIG:
AppConfig.Flags.bIsDHCPEnabled = TRUE;
break;
case MENU_CMD_DISABLE_AUTO_CONFIG:
AppConfig.Flags.bIsDHCPEnabled = FALSE;
break;
case MENU_CMD_DOWNLOAD_MPFS:
#if defined(MPFS_USE_EEPROM)
DownloadMPFS();
#endif
break;
case MENU_CMD_QUIT:
#if defined(MPFS_USE_EEPROM)
SaveAppConfig();
#endif
break;
}
}
static void SetConfig(void)
{
MENU_CMD choice;
do
{
putrsUART(menu);
choice = GetMenuChoice();
if ( choice != MENU_CMD_INVALID )
ExecuteMenuChoice(choice);
} while(choice != MENU_CMD_QUIT);
}
#if defined(MPFS_USE_EEPROM)
/*********************************************************************
* Function: BOOL DownloadMPFS(void)
*
* PreCondition: MPFSInit() is already called.
*
* Input: None
*
* Output: TRUE if successful
* FALSE otherwise
*
* Side Effects: This function uses 128 bytes of Bank 4 using
* indirect pointer. This requires that no part of
* code is using this block during or before calling
* this function. Once this function is done,
* that block of memory is available for general use.
*
* Overview: This function implements XMODEM protocol to
* be able to receive a binary file from PC
* applications such as HyperTerminal.
*
* Note: In current version, this function does not
* implement user interface to set IP address and
* other informations. User should create their
* own interface to allow user to modify IP
* information.
* Also, this version implements simple user
* action to start file transfer. User may
* evaulate its own requirement and implement
* appropriate start action.
*
********************************************************************/
#define XMODEM_SOH 0x01
#define XMODEM_EOT 0x04
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_CAN 0x18
#define XMODEM_BLOCK_LEN 128
static BOOL DownloadMPFS(void)
{
enum SM_MPFS
{
SM_MPFS_SOH,
SM_MPFS_BLOCK,
SM_MPFS_BLOCK_CMP,
SM_MPFS_DATA,
} state;
BYTE c;
MPFS handle;
BOOL lbDone;
BYTE blockLen;
BYTE lResult;
BYTE tempData[XMODEM_BLOCK_LEN];
TICK lastTick;
TICK currentTick;
state = SM_MPFS_SOH;
lbDone = FALSE;
handle = MPFSFormat();
// Notify the host that we are ready to receive...
lastTick = TickGet();
do
{
currentTick = TickGet();
if ( TickGetDiff(currentTick, lastTick) >= (TICK_SECOND/2) )
{
lastTick = TickGet();
while(BusyUART());
WriteUART(XMODEM_NAK);
/*
* Blink LED to indicate that we are waiting for
* host to send the file.
*/
LED6_IO ^= 1;
}
} while(!DataRdyUART());
while(!lbDone)
{
if(DataRdyUART())
{
// Toggle LED as we receive the data from host.
LED6_IO ^= 1;
c = ReadUART();
}
else
{
// Real application should put some timeout to make sure
// that we do not wait forever.
continue;
}
switch(state)
{
default:
if ( c == XMODEM_SOH )
{
state = SM_MPFS_BLOCK;
}
else if ( c == XMODEM_EOT )
{
// Turn off LED when we are done.
LED6_IO = 1;
MPFSClose();
while(BusyUART());
WriteUART(XMODEM_ACK);
lbDone = TRUE;
}
else
{
while(BusyUART());
WriteUART(XMODEM_NAK);
}
break;
case SM_MPFS_BLOCK:
// We do not use block information.
lResult = XMODEM_ACK;
blockLen = 0;
state = SM_MPFS_BLOCK_CMP;
break;
case SM_MPFS_BLOCK_CMP:
// We do not use 1's comp. block value.
state = SM_MPFS_DATA;
break;
case SM_MPFS_DATA:
// Buffer block data until it is over.
tempData[blockLen++] = c;
if ( blockLen > XMODEM_BLOCK_LEN )
{
// We have one block data. Write it to EEPROM.
MPFSPutBegin(handle);
lResult = XMODEM_ACK;
for ( c = 0; c < XMODEM_BLOCK_LEN; c++ )
MPFSPut(tempData[c]);
handle = MPFSPutEnd();
while(BusyUART());
WriteUART(lResult);
state = SM_MPFS_SOH;
}
break;
}
}
// This small wait is required if SLIP is in use.
// If this is not used, PC might misinterpret SLIP
// module communication and never close file transfer
// dialog box.
#if defined(STACK_USE_SLIP)
{
BYTE i = 255;
while(i--);
}
#endif
return TRUE;
}
#endif
static void FormatNetBIOSName(BYTE Name[16])
{
BYTE i;
Name[15] = '\0';
strupr(Name);
i = 0;
while(i < 15)
{
if(Name[i] == '\0')
{
while(i < 15)
{
Name[i++] = ' ';
}
break;
}
i++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -