jianghuai/SYSTEM/common.c
2024-05-07 09:36:09 +08:00

486 lines
13 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************************
** 文件名: common.c
** 版本: 1.0
** 工作环境: RealView MDK-ARM 4.14
** 作者: wuguoyana
** 生成日期: 2011-04-29
** 功能: 显示主菜单。主菜单上显示一系列操作,如加载二进制文件、
执行应用程序以及禁止写保护(如果事先Flash被写保护)。
** 相关文件: common.hymodem.h
** 修改日志: 2011-04-29 创建文档
*******************************************************************************/
/* 包含头文件 *****************************************************************/
#include "common.h"
#include "stm32f10x_flash.h"
/* 变量 ----------------------------------------------------------------------*/
pFunction Jump_To_Application;
uint32_t JumpAddress;
uint32_t BlockNbr = 0, UserMemoryMask = 0;
__IO uint32_t FlashProtection = 0;
uint32_t FlashDestination;
/*******************************************************************************
* @函数名称 Int2Str
* @函数说明 整形数据转到字符串
* @输入参数 intnum:数据
* @输出参数 str转换为的字符串
* @返回参数 无
*******************************************************************************/
void Int2Str(uint8_t* str, int32_t intnum)
{
uint32_t i, Div = 1000000000, j = 0, Status = 0;
for (i = 0; i < 10; i++)
{
str[j++] = (intnum / Div) + 48;
intnum = intnum % Div;
Div /= 10;
if ((str[j-1] == '0') & (Status == 0))
{
j = 0;
}
else
{
Status++;
}
}
}
/*******************************************************************************
* @函数名称 Int2Str
* @函数说明 字符串转到数据
* @输入参数 inputstr:需转换的字符串
* @输出参数 intnum转好的数据
* @返回参数 转换结果
1正确
0错误
*******************************************************************************/
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
{
uint32_t i = 0, res = 0;
uint32_t val = 0;
if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
{
if (inputstr[2] == '\0')
{
return 0;
}
for (i = 2; i < 11; i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
//返回1
res = 1;
break;
}
if (ISVALIDHEX(inputstr[i]))
{
val = (val << 4) + CONVERTHEX(inputstr[i]);
}
else
{
//无效输入返回0
res = 0;
break;
}
}
if (i >= 11)
{
res = 0;
}
}
else//最多10为2输入
{
for (i = 0; i < 11; i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
//返回1
res = 1;
break;
}
else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
{
val = val << 10;
*intnum = val;
res = 1;
break;
}
else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
{
val = val << 20;
*intnum = val;
res = 1;
break;
}
else if (ISVALIDDEC(inputstr[i]))
{
val = val * 10 + CONVERTDEC(inputstr[i]);
}
else
{
//无效输入返回0
res = 0;
break;
}
}
//超过10位无效返回0
if (i >= 11)
{
res = 0;
}
}
return res;
}
/*******************************************************************************
* @函数名称 Int2Str
* @函数说明 字符串转到数据
* @输入参数 inputstr:需转换的字符串
* @输出参数 intnum转好的数据
* @返回参数 转换结果
1正确
0错误
*******************************************************************************/
/**
* @brief Get an integer from the HyperTerminal
* @param num: The inetger
* @retval 1: Correct
* 0: Error
*/
uint32_t GetIntegerInput(int32_t * num)
{
uint8_t inputstr[16];
while (1)
{
GetInputString(inputstr);
if (inputstr[0] == '\0') continue;
if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
{
SerialPutString("User Cancelled \r\n");
return 0;
}
if (Str2Int(inputstr, num) == 0)
{
SerialPutString("Error, Input again: \r\n");
}
else
{
return 1;
}
}
}
/*******************************************************************************
* @函数名称 SerialKeyPressed
* @函数说明 测试超级终端是否有按键按下
* @输入参数 key:按键
* @输出参数 无
* @返回参数 1正确
0错误
*******************************************************************************/
uint32_t SerialKeyPressed(uint8_t *key)
{
if ( USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
*key = (uint8_t)USART1->DR;
return 1;
}
else
{
return 0;
}
}
/*******************************************************************************
* @函数名称 GetKey
* @函数说明 通过超级中断回去键码
* @输入参数 无
* @输出参数 无
* @返回参数 按下的键码
*******************************************************************************/
uint8_t GetKey(void)
{
uint8_t key = 0;
//等待按键按下
while (1)
{
if (SerialKeyPressed((uint8_t*)&key)) break;
}
return key;
}
/*******************************************************************************
* @函数名称 SerialPutChar
* @函数说明 串口发送一个字符
* @输入参数 C:需发送的字符
* @输出参数 i无
* @返回参数 无
*******************************************************************************/
void SerialPutChar(uint8_t c)
{
USART_SendData(USART1, c);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
}
/*******************************************************************************
* @函数名称 SerialPutChar
* @函数说明 串口发送一个字符串
* @输入参数 *s:需发送的字符串
* @输出参数 无
* @返回参数 无
*******************************************************************************/
void Serial_PutString(uint8_t *s)
{
while (*s != '\0')
{
SerialPutChar(*s);
s++;
}
}
/*******************************************************************************
* @函数名称 GetInputString
* @函数说明 从串口获取一个字符串
* @输入参数 *s:存字符串的地址
* @输出参数 无
* @返回参数 无
*******************************************************************************/
void GetInputString (uint8_t * buffP)
{
uint32_t bytes_read = 0;
uint8_t c = 0;
do
{
c = GetKey();
if (c == '\r')
break;
if (c == '\b')// Backspace 按键
{
if (bytes_read > 0)
{
SerialPutString("\b \b");
bytes_read --;
}
continue;
}
if (bytes_read >= CMD_STRING_SIZE )
{
SerialPutString("Command string size overflow\r\n");
bytes_read = 0;
continue;
}
if (c >= 0x20 && c <= 0x7E)
{
buffP[bytes_read++] = c;
SerialPutChar(c);
}
}
while (1);
SerialPutString(("\n\r"));
buffP[bytes_read] = '\0';
}
/*******************************************************************************
* @函数名称 FLASH_PagesMask
* @函数说明 计算Falsh页
* @输入参数 Size:文件长度
* @输出参数 无
* @返回参数 页的数量
*******************************************************************************/
uint32_t FLASH_PagesMask(__IO uint32_t Size)
{
uint32_t pagenumber = 0x0;
uint32_t size = Size;
if ((size % PAGE_SIZE) != 0)
{
pagenumber = (size / PAGE_SIZE) + 1;
}
else
{
pagenumber = size / PAGE_SIZE;
}
return pagenumber;
}
/*******************************************************************************
* @函数名称 FLASH_DisableWriteProtectionPages
* @函数说明 接触Flash写保护
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
void FLASH_DisableWriteProtectionPages(void)
{
uint32_t useroptionbyte = 0, WRPR = 0;
uint16_t var1 = OB_IWDG_SW, var2 = OB_STOP_NoRST, var3 = OB_STDBY_NoRST;
FLASH_Status status = FLASH_BUSY;
WRPR = FLASH_GetWriteProtectionOptionByte();
//测试是否写保护
if ((WRPR & UserMemoryMask) != UserMemoryMask)
{
useroptionbyte = FLASH_GetUserOptionByte();
UserMemoryMask |= WRPR;
status = FLASH_EraseOptionBytes();
if (UserMemoryMask != 0xFFFFFFFF)
{
status = FLASH_EnableWriteProtection((uint32_t)~UserMemoryMask);
}
//用处选项字是否有编程
if ((useroptionbyte & 0x07) != 0x07)
{
//重新保存选项字
if ((useroptionbyte & 0x01) == 0x0)
{
var1 = OB_IWDG_HW;
}
if ((useroptionbyte & 0x02) == 0x0)
{
var2 = OB_STOP_RST;
}
if ((useroptionbyte & 0x04) == 0x0)
{
var3 = OB_STDBY_RST;
}
FLASH_UserOptionByteConfig(var1, var2, var3);
}
if (status == FLASH_COMPLETE)
{
SerialPutString("Write Protection disabled...\r\n");
SerialPutString("...and a System Reset will be generated to re-load the new option bytes\r\n");
//系统复位重新加载选项字
NVIC_SystemReset();
}
else
{
SerialPutString("Error: Flash write unprotection failed...\r\n");
}
}
else
{
SerialPutString("Flash memory not write protected\r\n");
}
}
/*******************************************************************************
* @函数名称 Main_Menu
* @函数说明 显示菜单栏在超级终端
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
void Main_Menu(void)
{
uint8_t key = 0;
BlockNbr = (FlashDestination - 0x08000000) >> 12;
#if defined (STM32F10X_MD) || defined (STM32F10X_MD_VL)
UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1));
#else /* USE_STM3210E_EVAL */
if (BlockNbr < 62)
{
UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1));
}
else
{
UserMemoryMask = ((uint32_t)0x80000000);
}
#endif /* (STM32F10X_MD) || (STM32F10X_MD_VL) */
if ((FLASH_GetWriteProtectionOptionByte() & UserMemoryMask) != UserMemoryMask)
{
FlashProtection = 1;
}
else
{
FlashProtection = 0;
}
while (1)
{
SerialPutString("\r\n================== Main Menu ============================\r\n\n");
SerialPutString(" Download Image To the STM32F10x Internal Flash ------- 1\r\n\n");
SerialPutString(" Upload Image From the STM32F10x Internal Flash ------- 2\r\n\n");
SerialPutString(" Execute The New Program ------------------------------ 3\r\n\n");
if (FlashProtection != 0)
{
SerialPutString(" Disable the write protection ------------------------- 4\r\n\n");
}
SerialPutString("==========================================================\r\n\n");
key = GetKey();
if (key == 0x31)
{
//下载程序
// SerialDownload();
}
else if (key == 0x32)
{
//上传程序
// SerialUpload();
}
else if (key == 0x33)
{
SerialPutString("Execute user Program\r\n\n");
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
//跳转到用户程序
Jump_To_Application = (pFunction) JumpAddress;
//初始化用户程序的堆栈指针
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
else if ((key == 0x34) && (FlashProtection == 1))
{
//解除写保护
FLASH_DisableWriteProtectionPages();
}
else
{
if (FlashProtection == 0)
{
SerialPutString("Invalid Number ! ==> The number should be either 1, 2 or 3\r");
}
else
{
SerialPutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r");
}
}
}
}
/*******************************文件结束***************************************/