mirror of
https://github.com/armfly/H7-TOOL_STM32H7_App.git
synced 2024-08-09 10:05:34 +08:00
增加脱机烧录功能
This commit is contained in:
parent
239d4fb5f0
commit
92c24f60b8
@ -1,14 +1,51 @@
|
||||
【待解决】
|
||||
3. qspi_read(), lua连续读取存在问题. 2019-07-07
|
||||
|
||||
4. 文件管理界面,写字库操作1分钟,屏保进入后再唤醒,程序实际在刷屏函数中出不来。
|
||||
|
||||
2019-12-09 V1.07
|
||||
|
||||
1. systick 中断优先级 = 0、 stm32h7xx_hal_conf.h
|
||||
#define TICK_INT_PRIORITY 0 // ((uint32_t)0x0F) /*!< tick interrupt priority */
|
||||
|
||||
2. bsp_CheckRunTime, bsp_GetRunTime 函数内部去掉关闭中断的操作,影响QSPI写操作。
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
2020-02-06 V1.08 -- 主要增加脱机烧录功能
|
||||
1.脱机编程器功能(仅STM32芯片)
|
||||
- 通过文件浏览方式选择程序文件。不限制目录和文件个数。
|
||||
- FLM算法文件从KEIL MDK中复制出来,存放到emmc磁盘 \H7-TOOL\Programmer\FLM,按厂商分类
|
||||
- 目标程序文件、编程脚本存放到:\H7-TOOL\Programmer\User 文件夹。不限制目录级别和数量
|
||||
- 动态解析FLM文件,分离出内存镜像通过swd加载到目标cpu ram
|
||||
- 支持多段bin写入
|
||||
- 支持option bytes编程,烧录完毕设置读保护
|
||||
- 支持自动解除读保护
|
||||
- 支持动态填充产品序号、UID加密字段、用户自定义字段
|
||||
- 自动保存烧录次数,支持剩余次数限制功能
|
||||
- 支持连续烧录模式,检测到IC后自动烧录
|
||||
- 可动态显示CPU电压和供电电流
|
||||
- 通过lua脚本配置算法文件和数据文件(bin)以及控制编程过程
|
||||
- lua非常灵活,可以很方便扩充功能,比如:
|
||||
- 日期窗口段内才允许烧录
|
||||
- 目标板电流超限报警
|
||||
- 限定UID(CPU唯一序号)符合规则的才允许烧录
|
||||
- UID加密算法由用户自己定义
|
||||
- 填充任意短数据(小于1K),比如可以写入生产日期时间或客户代码
|
||||
- 关于程序文件保密问题。后期再考虑吧。
|
||||
- 因为H7-TOOL软件开源,文件结构开源,为了避免程序文件被加工厂泄露,初步设想如下:
|
||||
- 控制USB虚拟磁盘程序入口,增加人工输入密码。
|
||||
- 在虚拟磁盘扇区读写底层函数,以512字节为单位增加客户自定义加密和解密算法。这样emmc数据内容
|
||||
就是被加密的,即使emmc芯片被复制出来放到其他H7-TOOL主板也无法识别。
|
||||
|
||||
2.菜单变更
|
||||
- 联机模式长按S进入扩展功能菜单 : 脱机烧录器、LUA小程序、数据记录仪、系统设置
|
||||
- 系统设置下级菜单:硬件信息、参设设置、ESP32固件升级、USB eMMC磁盘、数据维护
|
||||
|
||||
【bug修复】
|
||||
V1.07 lua新增bug 不在lua小程序界面,执行PC机下下载lua程序会死机
|
||||
- bsp_tft_lcd.c LCD_DrawMemo()函数,增加: 3284行
|
||||
if (_pMemo->Text == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
2019-12-26 V1.07
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -313,7 +313,7 @@
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>1</Optim>
|
||||
<oTime>0</oTime>
|
||||
<oTime>1</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
<Strict>0</Strict>
|
||||
@ -338,7 +338,7 @@
|
||||
<MiscControls>--no-multibyte-chars;--locale=english</MiscControls>
|
||||
<Define>USE_HAL_DRIVER, STM32H743xx,USE_USB_HS,STM32H7,NO_HOST</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..\Libraries\CMSIS\Include;..\..\Libraries\CMSIS\Device\ST\STM32H7xx\Include;..\..\Libraries\STM32H7xx_HAL_Driver\Inc;..\..\User\bsp\inc;..\..\User;..\..\User\bsp;..\..\User\fonts;..\..\User\images;..\..\User\app\inc;..\..\Libraries\FatFs\src;..\..\Libraries\FatFs\src\drivers;..\..\Libraries\LwIP\src\include;..\..\Libraries\LwIP\src\apps;..\..\Libraries\LwIP\system;..\..\Libraries\LwIP\phy_drv;..\..\User\lwip_if;..\..\User\lwip_http;..\..\User\lwip_tcp;..\..\Libraries\STM32_USB_Device_Library\Core\Inc;..\..\Libraries\STM32_USB_Device_Library\Class\MSC\Inc;..\..\User\modbus;..\..\User\programmer;..\..\User\lua\src;..\..\User\lua\if;..\..\User\st_usb;..\..\User\st_usb\usbd_virtual_com;..\..\User\st_usb\usbd_mass_storage;..\..\Libraries\STM32_USB_Device_Library\Class\CDC\Inc;..\..\User\daplink\source\daplink\cmsis-dap;..\..\User\daplink\source\target;..\..\User\daplink\source\family\st\stm32h7;..\..\User\daplink\source\hic_hal;..\..\User\daplink\source\daplink;..\..\User\daplink\source\hic_hal\stm32\stm32h750;..\..\User\daplink\source\rtos_none;..\..\User\daplink\source\daplink\interface;..\..\User\daplink\source\daplink\settings;..\..\User\daplink\source\usb;..\..\User\teeny_usb\usb_stack\inc;..\..\User\teeny_usb\usb_stack\class;..\..\User\teeny_usb\usb_app</IncludePath>
|
||||
<IncludePath>..\..\Libraries\CMSIS\Include;..\..\Libraries\CMSIS\Device\ST\STM32H7xx\Include;..\..\Libraries\STM32H7xx_HAL_Driver\Inc;..\..\User\bsp\inc;..\..\User;..\..\User\bsp;..\..\User\fonts;..\..\User\images;..\..\User\app\inc;..\..\Libraries\FatFs\src;..\..\Libraries\FatFs\src\drivers;..\..\Libraries\LwIP\src\include;..\..\Libraries\LwIP\src\apps;..\..\Libraries\LwIP\system;..\..\Libraries\LwIP\phy_drv;..\..\User\lwip_if;..\..\User\lwip_http;..\..\User\lwip_tcp;..\..\Libraries\STM32_USB_Device_Library\Core\Inc;..\..\Libraries\STM32_USB_Device_Library\Class\MSC\Inc;..\..\User\modbus;..\..\User\programmer;..\..\User\lua\src;..\..\User\lua\if;..\..\User\st_usb;..\..\User\st_usb\usbd_virtual_com;..\..\User\st_usb\usbd_mass_storage;..\..\Libraries\STM32_USB_Device_Library\Class\CDC\Inc;..\..\User\daplink\source\daplink\cmsis-dap;..\..\User\daplink\source\target;..\..\User\daplink\source\family\st\stm32h7;..\..\User\daplink\source\hic_hal;..\..\User\daplink\source\daplink;..\..\User\daplink\source\hic_hal\stm32\stm32h750;..\..\User\daplink\source\rtos_none;..\..\User\daplink\source\daplink\interface;..\..\User\daplink\source\daplink\settings;..\..\User\daplink\source\usb;..\..\User\teeny_usb\usb_stack\inc;..\..\User\teeny_usb\usb_stack\class;..\..\User\teeny_usb\usb_app;..\..\User\daplink\source\target</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@ -417,16 +417,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_system_set.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>status_current_meter.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_current_meter.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>status_resistor_meter.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_resistor_meter.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>status_current_meter.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_current_meter.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>status_temp_meter.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -467,67 +467,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_lua.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>demo_sd_fatfs.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\demo_sd_fatfs.c</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>0</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>file_lib.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\file_lib.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>status_mini_dso.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\app\src\status_mini_dso.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
@ -1014,6 +963,16 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Libraries\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mmc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32h7xx_hal_crc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Libraries\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_crc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32h7xx_hal_crc_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Libraries\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_crc_ex.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
@ -1514,6 +1473,36 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\programmer\prog_if.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>elf_file.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\programmer\elf_file.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>falsh_error.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\programmer\falsh_error.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>SWD_flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\User\programmer\SWD_flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>flash_blob.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\..\User\programmer\flash_blob.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>FlashOS.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\..\User\programmer\FlashOS.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>SWD_flash.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\..\User\programmer\SWD_flash.h</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
@ -33,7 +33,7 @@
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x9200
|
||||
Stack_Size EQU 0x7000
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
@ -44,7 +44,7 @@ __initial_sp
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00020000 ;0x00012000 ?
|
||||
Heap_Size EQU 0x0001F000 ;0x00012000 ?
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
@ -68,7 +68,7 @@ __Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0x00000107 ; Reserved H7-TOOL APP 固件版本
|
||||
DCD 0x00000108 ; Reserved H7-TOOL APP 固件版本
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
|
BIN
Project/h7_tool_app(V1.08).bin
Normal file
BIN
Project/h7_tool_app(V1.08).bin
Normal file
Binary file not shown.
@ -14,6 +14,18 @@
|
||||
#include "ff_gen_drv.h"
|
||||
#include "sd_diskio_dma.h"
|
||||
|
||||
/* Lua程序根目录 */
|
||||
#define LUA_ROOT_DIR "0:/H7-TOOL/Lua"
|
||||
|
||||
/* 脱机编程器用户文件目录 */
|
||||
#define PROG_USER_DIR "0:/H7-TOOL/Programmer/User"
|
||||
|
||||
/* 脱机编程器算法文件目录 */
|
||||
#define PROG_FLM_DIR "0:/H7-TOOL/Programmer/FLM"
|
||||
|
||||
/* 脱机编程器启动配置文件 */
|
||||
#define PROG_AUTORUN_FILE "0:/H7-TOOL/Programmer/User/autorun.ini"
|
||||
|
||||
/* 静态分配,单个目录下最多100个文件 */
|
||||
#define FILE_MAX_NUM 100
|
||||
#define FILE_NAME_MAX_LEN 32 /* 32字符, 只显示前面16字符 */
|
||||
@ -27,26 +39,53 @@ typedef struct
|
||||
char Path[200];
|
||||
}FILE_LIST_T;
|
||||
|
||||
extern FILE_LIST_T g_tFileList;
|
||||
/* prog ini文件结构 */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Locked; /* 程序锁死标志,1表示锁死,需要人工解除 */
|
||||
|
||||
uint32_t ProgramLimit; /* 烧录次数限制 0表示不限制 */
|
||||
uint32_t ProgrammedCount;
|
||||
|
||||
uint32_t ProductSN; /* 产品序号(整数部分) */
|
||||
|
||||
uint32_t LastTotalTime; /* 上次编程总时间 */
|
||||
uint32_t LastEraseChipTime; /* 擦除整片的时间,仅仅用于进度指示. 按扇区擦除时不用这个变量 */
|
||||
}PROG_INI_T;
|
||||
|
||||
extern PROG_INI_T g_tProgIni;
|
||||
extern FILE_LIST_T g_tFileList;
|
||||
|
||||
extern FATFS fs;
|
||||
extern FIL g_file;
|
||||
extern char FsReadBuf[1024];
|
||||
extern char FsReadBuf[16*1024];
|
||||
extern char FsWriteBuf[1024];
|
||||
|
||||
extern DIR DirInf;
|
||||
extern FILINFO FileInf;
|
||||
extern char DiskPath[4]; /* SD卡逻辑驱动路径,比盘符0,就是"0:/" */
|
||||
|
||||
|
||||
void FileSystemLoad(void);
|
||||
void FileSystemUnLoad(void);
|
||||
uint8_t CreateNewFile(char *_FileName);
|
||||
uint8_t CloseFile(FIL *_file);
|
||||
uint8_t DeleteFile(char *_Path);
|
||||
uint8_t ReadFile(FIL* fp, void* buff, UINT btr, UINT* br);
|
||||
uint8_t WriteFile(FIL* fp, const void* buff, UINT btw, UINT* bw);
|
||||
uint8_t OpenFile(FIL* fp, char *_Path);
|
||||
void ListDir(char *_Path);
|
||||
uint32_t ReadFileToMem(char *_Path, char *_Buff, uint32_t _MaxLen);
|
||||
void ListDir(char *_Path, char *_Filter);
|
||||
uint32_t ReadFileToMem(char *_Path, uint32_t _offset, char *_Buff, uint32_t _MaxLen);
|
||||
uint8_t SelectFile(char *_InitPath, uint16_t _MainStatus, uint16_t _RetStatus, char *_Filter);
|
||||
|
||||
uint32_t GetFileSize(char *_Path);
|
||||
uint8_t CheckFileNamePostfix(char *_Path, char *_Filter);
|
||||
void GetDirOfFileName(char *_Path, char *_Dir);
|
||||
void FixFileName(char *_Path);
|
||||
|
||||
|
||||
void ini_ReadString(const char *_IniBuf, const char *_ParamName, char *_OutBuff, int32_t _BuffSize);
|
||||
int32_t ini_ReadInteger(const char *_IniBuf, const char *_ParamName);
|
||||
void ini_WriteString(const char *_IniBuf, const char *_ParamName, const char *_NewStr, uint32_t _IniBufSize);
|
||||
void ini_WriteInteger(const char *_IniBuf, const char *_ParamName, int _IntValue, uint32_t _IniBufSize);
|
||||
int32_t ReadProgIniFile(char *_LuaPath, PROG_INI_T *pIni);
|
||||
int32_t WriteProgIniFile(char *_LuaPath, PROG_INI_T *_pIni);
|
||||
void LoadProgAutorunFile(char *_OutBuff, uint32_t _BuffSize);
|
||||
void SaveProgAutorunFile(const char *_NewStr);
|
||||
|
||||
#endif
|
||||
|
@ -17,33 +17,34 @@
|
||||
/* 主程序状态字定义, MS = Main Status */
|
||||
enum
|
||||
{
|
||||
MS_LINK_MODE = 0, /* 联机状态 */
|
||||
MS_LINK_MODE = 0, /* 联机状态 */
|
||||
|
||||
MS_SYSTEM_SET, /* 系统设置 */
|
||||
MS_HARD_INFO, /* 关于-硬件信息 */
|
||||
MS_ESP32_TEST, /* ESP32模块升级状态 */
|
||||
MS_USB_EMMC, /* 虚拟串口状态。RS232 RS485 TTL-UART */
|
||||
MS_MODIFY_PARAM, /* 参数设置 */
|
||||
MS_FILE_MANAGE, /* 文件管理 */
|
||||
MS_SYSTEM_SET, /* 系统设置 */
|
||||
MS_HARD_INFO, /* 关于-硬件信息 */
|
||||
MS_ESP32_TEST, /* ESP32模块升级状态 */
|
||||
MS_USB_EMMC, /* 虚拟串口状态。RS232 RS485 TTL-UART */
|
||||
MS_MODIFY_PARAM, /* 参数设置 */
|
||||
MS_FILE_MANAGE, /* 文件管理 */
|
||||
|
||||
MS_PROG_INIT, /* 脱机下载器预览界面 */
|
||||
MS_PROG_WORK, /* 脱机下载器正式界面 */
|
||||
MS_PROG_SELECT_FILE, /* 脱机下载器浏览文件 */
|
||||
MS_PROG_WORK, /* 脱机下载器工作界面 */
|
||||
MS_PROG_SETTING, /* 脱机下载器临时参数设置 */
|
||||
|
||||
MS_VOLTAGE_METER, /* 电压表 */
|
||||
MS_CURRENT_METER, /* 高侧电流表 */
|
||||
MS_TEMP_METER, /* 温度表 */
|
||||
MS_RESISTOR_METER, /* 电阻表 */
|
||||
MS_TVCC_POWER, /* 微型数控电源 */
|
||||
MS_PULSE_METER, /* 脉冲计 */
|
||||
MS_VOLTAGE_METER, /* 电压表 */
|
||||
MS_CURRENT_METER, /* 高侧电流表 */
|
||||
MS_TEMP_METER, /* 温度表 */
|
||||
MS_RESISTOR_METER, /* 电阻表 */
|
||||
MS_TVCC_POWER, /* 微型数控电源 */
|
||||
MS_PULSE_METER, /* 脉冲计 */
|
||||
|
||||
MS_EXTEND_INIT, /* 扩展菜单显示 */
|
||||
MS_EXTEND_MENU1, /* 第1级菜单 */
|
||||
MS_EXTEND_MENU_LUA, /* 第2级菜单-LUA程序 */
|
||||
MS_EXTEND_MENU_REC, /* 第2级菜单-数据记录仪 */
|
||||
MS_MINI_DSO, /* 迷你示波器 */
|
||||
|
||||
MS_EXTEND_MENU1, /* 第1级菜单 */
|
||||
MS_EXTEND_MENU_LUA, /* 第2级菜单-LUA程序 */
|
||||
MS_EXTEND_MENU_REC, /* 第2级菜单-数据记录仪 */
|
||||
|
||||
MS_LUA_SELECT_FILE, /* 浏览lua文件 */
|
||||
MS_LUA_EXEC_FILE, /* 执行lua文件 */
|
||||
MS_LUA_SELECT_FILE, /* 浏览lua文件 */
|
||||
MS_LUA_EXEC_FILE, /* 执行lua文件 */
|
||||
};
|
||||
|
||||
void DispHeader(char *_str);
|
||||
@ -60,7 +61,7 @@ void DispBox(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth
|
||||
void DispLabel(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth,
|
||||
uint16_t _usColor, char *_pStr, FONT_T *_tFont);
|
||||
void DispProgressBar(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth,
|
||||
char *_str, uint8_t _ucPercent, FONT_T *_tFont);
|
||||
char *_str, float _Percent, FONT_T *_tFont);
|
||||
uint16_t NextStatus(uint16_t _NowStatus);
|
||||
uint16_t LastStatus(uint16_t _NowStatus);
|
||||
void DSO_StartMode2(void);
|
||||
|
@ -95,11 +95,11 @@ typedef struct
|
||||
uint32_t TestWord; /* 测试单元,用于检测eepromg功能 */
|
||||
uint8_t NtcType; /* NTC热敏电阻类型 0 = 10K_B3950,1 = 100K_B3950 */
|
||||
|
||||
/* V2.04追加 */
|
||||
uint8_t KeyToneEnable;
|
||||
uint8_t UIStyle; /* UI风格 */
|
||||
uint16_t LcdSleepTime; /* 屏保时间 */
|
||||
|
||||
uint8_t FileListFont24; /* 1表示24点阵显示文件列表,0表示16点阵 */
|
||||
} PARAM_T;
|
||||
|
||||
/* 模拟量校准参数 */
|
||||
|
17
User/app/inc/status_mini_dso.h
Normal file
17
User/app/inc/status_mini_dso.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : 迷你示波器
|
||||
* 文件名称 : status_mini_dso.h
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _STATUS_MINI_DSO_H_
|
||||
#define _STATUS_MINI_DSO_H_
|
||||
|
||||
void status_MiniDSO(void);
|
||||
|
||||
#endif
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
@ -10,7 +10,9 @@
|
||||
#ifndef _STATUS_PROGRAMMER_H_
|
||||
#define _STATUS_PROGRAMMER_H_
|
||||
|
||||
void status_ProgSelectFile(void);
|
||||
void status_ProgWork(void);
|
||||
void status_ProgSetting(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
*/
|
||||
#include "bsp.h"
|
||||
#include "file_lib.h"
|
||||
#include "lcd_menu.h"
|
||||
#include "main.h"
|
||||
#include "prog_if.h"
|
||||
|
||||
/*
|
||||
1、V7开发板的SD卡接口是用的SDMMC1,而这个接口仅支持AXI SRAM区访问,其它SRAM和TCP均不支持。
|
||||
@ -29,15 +32,15 @@ FATFS fs;
|
||||
#pragma location = 0x24001000
|
||||
FIL file;
|
||||
#pragma location = 0x24002000
|
||||
char FsReadBuf[1024];
|
||||
char FsReadBuf[8*1024];
|
||||
#pragma location = 0x24003000
|
||||
char FsWriteBuf[1024] = {"FatFS Write Demo \r\n www.armfly.com \r\n"};
|
||||
char FsWriteBuf[8*1024] = {"FatFS Write Demo \r\n www.armfly.com \r\n"};
|
||||
#pragma location = 0x24004000
|
||||
uint8_t g_TestBuf[BUF_SIZE];
|
||||
#elif defined(__CC_ARM)
|
||||
__attribute__((section(".RAM_D1"))) FATFS fs;
|
||||
__attribute__((section(".RAM_D1"))) FIL g_file;
|
||||
ALIGN_32BYTES(__attribute__((section(".RAM_D1"))) char FsReadBuf[1024]);
|
||||
ALIGN_32BYTES(__attribute__((section(".RAM_D1"))) char FsReadBuf[16*1024]);
|
||||
ALIGN_32BYTES(__attribute__((section(".RAM_D1"))) char FsWriteBuf[1024]) = {"FatFS Write Demo \r\n www.armfly.com \r\n"};
|
||||
#endif
|
||||
|
||||
@ -74,6 +77,14 @@ static const char *FR_Table[] =
|
||||
|
||||
FILE_LIST_T g_tFileList;
|
||||
|
||||
uint8_t *g_MenuLua_Text[FILE_MAX_NUM + 1] =
|
||||
{
|
||||
/* 结束符号, 用于菜单函数自动识别菜单项个数 */
|
||||
"&"
|
||||
};
|
||||
|
||||
MENU_T g_tMenuLua;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: FileSystemLoad
|
||||
@ -184,12 +195,13 @@ uint8_t DeleteFile(char *_Path)
|
||||
* 函 数 名: ReadFileToMem
|
||||
* 功能说明: 读取完整的文件到内存
|
||||
* 形 参: _Path : 文件路径+文件名
|
||||
* _offset : 文件偏移地址
|
||||
* _Buff : 目标缓冲区
|
||||
* _MaxLen : 最大长度
|
||||
* 返 回 值: 读到的数据长度。 0 表示失败。
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint32_t ReadFileToMem(char *_Path, char *_Buff, uint32_t _MaxLen)
|
||||
uint32_t ReadFileToMem(char *_Path, uint32_t _offset, char *_Buff, uint32_t _MaxLen)
|
||||
{
|
||||
FRESULT re;
|
||||
uint32_t br;
|
||||
@ -199,7 +211,12 @@ uint32_t ReadFileToMem(char *_Path, char *_Buff, uint32_t _MaxLen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (_offset > 0)
|
||||
{
|
||||
f_lseek(&g_file, _offset);
|
||||
}
|
||||
|
||||
re = f_read(&g_file, _Buff, _MaxLen, &br);
|
||||
f_close(&g_file);
|
||||
|
||||
@ -208,29 +225,631 @@ uint32_t ReadFileToMem(char *_Path, char *_Buff, uint32_t _MaxLen)
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: WriteFile
|
||||
* 功能说明: 读取文件
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
* 函 数 名: GetFileSize
|
||||
* 功能说明: 得到文件长度
|
||||
* 形 参: _Path : 文件路径+文件名*
|
||||
* 返 回 值: 文件长度。0表示失败。
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
FRESULT WriteFile(FIL* fp, const void* buff, UINT btw, UINT* bw)
|
||||
uint32_t GetFileSize(char *_Path)
|
||||
{
|
||||
return f_write(fp, buff, btw, bw);
|
||||
FRESULT re;
|
||||
uint32_t size;
|
||||
|
||||
re = f_open(&g_file, _Path, FA_OPEN_EXISTING | FA_READ);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = f_size(&g_file);
|
||||
|
||||
f_close(&g_file);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: OpenFile
|
||||
* 功能说明: 打开一个已存在的文件进行读写
|
||||
* 函 数 名: ini_ReadString
|
||||
* 功能说明: 读ini文件中的字符串变量。简化版,不支持[]分组,需要保证每个ini参数名唯一. 字符串内容不支持引号
|
||||
* 形 参: _IniFileBuf : 文件内容缓冲区
|
||||
* _ParamName : 参数名(区分大小写)
|
||||
* _pOutString : 输出结果
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void ini_ReadString(const char *_IniBuf, const char *_ParamName, char *_OutBuff, int32_t _BuffSize)
|
||||
{
|
||||
/*
|
||||
Count = -1
|
||||
ProductSN = 0
|
||||
Path = "1234"
|
||||
*/
|
||||
char *p;
|
||||
|
||||
p = strstr(_IniBuf, _ParamName);
|
||||
if (p == 0)
|
||||
{
|
||||
_OutBuff[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = strstr(p, "=");
|
||||
if (p == 0)
|
||||
{
|
||||
_OutBuff[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = strstr( p++, "\"");
|
||||
if (p == 0)
|
||||
{
|
||||
_OutBuff[0] = 0;
|
||||
return;
|
||||
}
|
||||
p++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (*p == 0 || *p == '"')
|
||||
{
|
||||
*_OutBuff = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*_OutBuff++ = *p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ini_WriteString
|
||||
* 功能说明: 写ini文件中的字符串变量。简化版,不支持[]分组,需要保证每个ini参数名唯一. 字符串内容不支持引号
|
||||
* 形 参: _IniFileBuf : 文件内容缓冲区
|
||||
* _ParamName : 参数名(区分大小写)
|
||||
* _OutBuff : 输出结果
|
||||
* _BuffSize : 输出缓冲区大小
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void ini_WriteString(const char *_IniBuf, const char *_ParamName, const char *_NewStr, uint32_t _IniBufSize)
|
||||
{
|
||||
/*
|
||||
Count = -1
|
||||
ProductSN = 0
|
||||
Path = "1234"
|
||||
*/
|
||||
char *p;
|
||||
char *p1, *p2, *p3, *p4;
|
||||
int len, len2;
|
||||
int i;
|
||||
|
||||
p = strstr(_IniBuf, _ParamName);
|
||||
if (p == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = strstr(p, "=");
|
||||
if (p == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
p1 = p + 1;
|
||||
|
||||
p2 = strstr(p, "\r");
|
||||
if (p2 == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen(_NewStr);
|
||||
if (p2 - p1 > len + 2) /* 将后面的字符串前移 */
|
||||
{
|
||||
memcpy(p1, " \"", 2); p1 += 2;
|
||||
memcpy(p1, _NewStr, len); p1 += len;
|
||||
memcpy(p1, "\"", 1); p1 += 1;
|
||||
|
||||
while(1)
|
||||
{
|
||||
*p1++ = *p2++;
|
||||
|
||||
if (*p2 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* 将后面的字符串后移,挪出空间存放新字符串 p1 p2 尾部 p3 --- p4 */
|
||||
{
|
||||
len2 = strlen(p2);
|
||||
p3 = len2 + p2;
|
||||
p4 = (p1 + len + 2) + len2;
|
||||
|
||||
if (p4 - _IniBuf > _IniBufSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
{
|
||||
*p4-- = *p3--;
|
||||
}
|
||||
|
||||
memcpy(p1, " \"", 2); p1 += 2;
|
||||
memcpy(p1, _NewStr, len); p1 += len;
|
||||
memcpy(p1, "\"", 1); p1 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ini_ReadString
|
||||
* 功能说明: 读ini文件中的整数变量。简化版,不支持[]分组,需要保证每个ini参数名唯一
|
||||
* 形 参: _IniFileBuf : 文件内容缓冲区
|
||||
* _ParamName : 参数名(区分大小写)
|
||||
* 返 回 值: 读到的整数值。如果没找到则返回0
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
int32_t ini_ReadInteger(const char *_IniBuf, const char *_ParamName)
|
||||
{
|
||||
/*
|
||||
Count = -1
|
||||
ProductSN = 0
|
||||
Path = "1234"
|
||||
*/
|
||||
char *p;
|
||||
|
||||
p = strstr(_IniBuf, _ParamName);
|
||||
if (p == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = strstr(p, "=");
|
||||
if (p == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return str_to_int3(p + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ini_WriteInteger
|
||||
* 功能说明: 写ini文件中的整数变量。简化版,不支持[]分组,需要保证每个ini参数名唯一. 字符串内容不支持引号
|
||||
* 形 参: _IniFileBuf : 文件内容缓冲区
|
||||
* _ParamName : 参数名(区分大小写)
|
||||
* _OutBuff : 输出结果
|
||||
* _BuffSize : 输出缓冲区大小
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void ini_WriteInteger(const char *_IniBuf, const char *_ParamName, int _IntValue, uint32_t _IniBufSize)
|
||||
{
|
||||
/*
|
||||
Count = -1
|
||||
ProductSN = 0
|
||||
Path = "1234"
|
||||
*/
|
||||
char *p;
|
||||
char *p1, *p2, *p3, *p4;
|
||||
int len, len2;
|
||||
int i;
|
||||
char NewStr[32];
|
||||
|
||||
p = strstr(_IniBuf, _ParamName);
|
||||
if (p == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = strstr(p, "=");
|
||||
if (p == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
p1 = p + 1;
|
||||
|
||||
p2 = strstr(p, "\r");
|
||||
if (p2 == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(NewStr, " %d", _IntValue);
|
||||
|
||||
len = strlen(NewStr);
|
||||
if (p2 - p1 > len) /* 将后面的字符串前移 */
|
||||
{
|
||||
memcpy(p1, NewStr, len); p1 += len;
|
||||
|
||||
while(1)
|
||||
{
|
||||
*p1++ = *p2++;
|
||||
|
||||
if (*p2 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* 将后面的字符串后移,挪出空间存放新字符串 p1 p2 尾部 p3 --- p4 */
|
||||
{
|
||||
len2 = strlen(p2);
|
||||
p3 = len2 + p2;
|
||||
p4 = (p1 + len + 0) + len2;
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
{
|
||||
*p4-- = *p3--;
|
||||
}
|
||||
|
||||
memcpy(p1, NewStr, len); p1 += len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ReadProgIniFile
|
||||
* 功能说明: 读ini文件. 使用了全局变量 FsReadBuf[]
|
||||
* 形 参: _Path : 文件路径+文件名 .lua文件,后缀改为.ini作为计数文件
|
||||
* 返 回 值: -1表示错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
int32_t ReadProgIniFile(char *_LuaPath, PROG_INI_T *pIni)
|
||||
{
|
||||
FRESULT re;
|
||||
uint32_t FileSize;
|
||||
|
||||
char path[256];
|
||||
uint16_t len;
|
||||
|
||||
len = strlen(_LuaPath);
|
||||
|
||||
if (len > sizeof(path))
|
||||
{
|
||||
/* 文件名过长 */
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
/* 将 *.lua 文件修改为 *.txt */
|
||||
memcpy(path, _LuaPath, len);
|
||||
path[len - 3] = 'i';
|
||||
path[len - 2] = 'n';
|
||||
path[len - 1] = 'i';
|
||||
path[len] = 0;
|
||||
|
||||
/* 打开ini文件 */
|
||||
re = f_open(&g_file, path, FA_OPEN_EXISTING | FA_READ);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
/* 将ini文件全部内容读到内存 16KB */
|
||||
re = f_read(&g_file, FsReadBuf, sizeof(FsReadBuf), &FileSize);
|
||||
if (re != FR_OK || FileSize == 0)
|
||||
{
|
||||
f_close(&g_file);
|
||||
goto err_quit;
|
||||
}
|
||||
FsReadBuf[FileSize] = 0;
|
||||
|
||||
f_close(&g_file);
|
||||
|
||||
/* 解析 Locked */
|
||||
pIni->Locked = ini_ReadInteger(FsReadBuf, "Locked");
|
||||
|
||||
/* 解析 ProgramLimit */
|
||||
pIni->ProgramLimit = ini_ReadInteger(FsReadBuf, "ProgramLimit");
|
||||
|
||||
/* 解析 ProgrammedCount */
|
||||
pIni->ProgrammedCount = ini_ReadInteger(FsReadBuf, "ProgrammedCount");
|
||||
|
||||
/* 解析 ProductSN */
|
||||
pIni->ProductSN = ini_ReadInteger(FsReadBuf, "ProductSN");
|
||||
|
||||
/* 上次编程总时间 */
|
||||
pIni->LastTotalTime = ini_ReadInteger(FsReadBuf, "LastTotalTime");
|
||||
|
||||
/* 擦除整片的时间 */
|
||||
pIni->LastEraseChipTime = ini_ReadInteger(FsReadBuf, "LastEraseChipTime");
|
||||
|
||||
return 1;
|
||||
|
||||
err_quit:
|
||||
pIni->Locked = 0;
|
||||
pIni->ProductSN = 0;
|
||||
pIni->ProgramLimit = 0;
|
||||
pIni->ProgrammedCount = 0;
|
||||
pIni->LastTotalTime = 0;
|
||||
pIni->LastEraseChipTime = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: WriteProgIniFile
|
||||
* 功能说明: 写ini文件. 使用了全局变量 FsReadBuf[]
|
||||
* 形 参: _Path : 文件路径+文件名 .lua文件,后缀改为.ini作为计数文件
|
||||
* _pIni : ini文件变量
|
||||
* 返 回 值: -1表示错误 1表示OK
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
int32_t WriteProgIniFile(char *_LuaPath, PROG_INI_T *_pIni)
|
||||
{
|
||||
FRESULT re;
|
||||
uint32_t FileSize;
|
||||
|
||||
char path[256];
|
||||
uint16_t len;
|
||||
|
||||
len = strlen(_LuaPath);
|
||||
|
||||
if (len > sizeof(path))
|
||||
{
|
||||
/* 文件名过长 */
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
/* 将 *.lua 文件修改为 *.txt */
|
||||
memcpy(path, _LuaPath, len);
|
||||
path[len - 3] = 'i';
|
||||
path[len - 2] = 'n';
|
||||
path[len - 1] = 'i';
|
||||
path[len] = 0;
|
||||
|
||||
sprintf(FsReadBuf, "Locked = %d\r\n", _pIni->Locked);
|
||||
sprintf(&FsReadBuf[strlen(FsReadBuf)], "ProgramLimit = %d\r\n", _pIni->ProgramLimit);
|
||||
sprintf(&FsReadBuf[strlen(FsReadBuf)], "ProgrammedCount = %d\r\n", _pIni->ProgrammedCount);
|
||||
sprintf(&FsReadBuf[strlen(FsReadBuf)], "ProductSN = %d\r\n", _pIni->ProductSN);
|
||||
sprintf(&FsReadBuf[strlen(FsReadBuf)], "LastTotalTime = %d\r\n", _pIni->LastTotalTime);
|
||||
sprintf(&FsReadBuf[strlen(FsReadBuf)], "LastEraseChipTime = %d\r\n", _pIni->LastEraseChipTime);
|
||||
|
||||
/* 打开ini文件准备写 */
|
||||
re = f_open(&g_file, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
re = f_write(&g_file, FsReadBuf, strlen(FsReadBuf), &FileSize);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
f_close(&g_file);
|
||||
return 0;
|
||||
|
||||
err_quit:
|
||||
f_close(&g_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: LoadProgAutorunFile
|
||||
* 功能说明: 读Autorun.ini文件. 使用了全局变量 FsReadBuf[]
|
||||
* 形 参: _OutPath : 读到的结果保存在这个缓冲区
|
||||
* 返 回 值: -1表示错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void LoadProgAutorunFile(char *_OutBuff, uint32_t _BuffSize)
|
||||
{
|
||||
FRESULT re;
|
||||
uint32_t FileSize;
|
||||
|
||||
/* 打开ini文件 */
|
||||
re = f_open(&g_file, PROG_AUTORUN_FILE, FA_OPEN_EXISTING | FA_READ);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
/* 将ini文件全部内容读到内存 16KB */
|
||||
re = f_read(&g_file, FsReadBuf, sizeof(FsReadBuf), &FileSize);
|
||||
if (re != FR_OK || FileSize == 0)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
FsReadBuf[FileSize] = 0;
|
||||
|
||||
f_close(&g_file);
|
||||
|
||||
ini_ReadString(FsReadBuf, "DefaultLuaFile", _OutBuff, _BuffSize);
|
||||
return;
|
||||
|
||||
err_quit:
|
||||
f_close(&g_file);
|
||||
_OutBuff[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: SaveProgAutorunFile
|
||||
* 功能说明: 更新修改Autorun.ini文件. 使用了全局变量 FsReadBuf[]
|
||||
* 形 参: _OutPath : 读到的结果保存在这个缓冲区
|
||||
* 返 回 值: -1表示错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void SaveProgAutorunFile(const char *_NewStr)
|
||||
{
|
||||
FRESULT re;
|
||||
uint32_t FileSize;
|
||||
|
||||
// /* 打开ini文件 */
|
||||
// re = f_open(&g_file, PROG_AUTORUN_FILE, FA_OPEN_EXISTING | FA_READ);
|
||||
// if (re != FR_OK)
|
||||
// {
|
||||
// goto err_quit;
|
||||
// }
|
||||
//
|
||||
// /* 将ini文件全部内容读到内存 16KB */
|
||||
// re = f_read(&g_file, FsReadBuf, sizeof(FsReadBuf), &FileSize);
|
||||
// if (re != FR_OK || FileSize == 0)
|
||||
// {
|
||||
// f_close(&g_file);
|
||||
// goto err_quit;
|
||||
// }
|
||||
// FsReadBuf[FileSize] = 0;
|
||||
//
|
||||
// f_close(&g_file);
|
||||
|
||||
// ini_WriteString(FsReadBuf, "DefaultLuaFile", _NewStr, sizeof(FsReadBuf));
|
||||
|
||||
|
||||
sprintf(FsReadBuf, "DefaultLuaFile = \"%s\"", _NewStr);
|
||||
|
||||
/* 打开ini文件准备写 */
|
||||
re = f_open(&g_file, PROG_AUTORUN_FILE, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
re = f_write(&g_file, FsReadBuf, strlen(FsReadBuf), &FileSize);
|
||||
if (re != FR_OK)
|
||||
{
|
||||
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
err_quit:
|
||||
f_close(&g_file);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: GetFileNamePostfix
|
||||
* 功能说明: 获得文件名的后缀,不包括小数点。 1234.lua 则返回 "lua".
|
||||
* 形 参: _Path : 完整的路径带文件名
|
||||
* _Dir : 去掉文件名后的路径,不带斜杠
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void GetDirOfFileName(char *_Path, char *_Dir)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t i;
|
||||
|
||||
len = strlen(_Path);
|
||||
|
||||
for (i = len; i > 0; i--)
|
||||
{
|
||||
if (_Path[i] == '/')
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
_Dir[i] = _Path[i];
|
||||
}
|
||||
_Dir[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: GetFileNamePostfix
|
||||
* 功能说明: 获得文件名的后缀,不包括小数点。 1234.lua 则返回 "lua".
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
FRESULT OpenFile(FIL* fp, char *_Path)
|
||||
char *GetFileNamePostfix(char *_Path)
|
||||
{
|
||||
//f_open(&file, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
return f_open(fp, _Path, FA_OPEN_EXISTING | FA_READ);
|
||||
uint16_t len;
|
||||
uint8_t i;
|
||||
|
||||
len = strlen(_Path);
|
||||
|
||||
for (i = len; i > 0; i--)
|
||||
{
|
||||
if (_Path[i] == '.')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
return &_Path[len];
|
||||
}
|
||||
return &_Path[i];
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: CheckFileNamePostfix
|
||||
* 功能说明: 判断文件名后缀是否在过滤器内
|
||||
* 形 参: _Path 文件名
|
||||
* _Filter 过滤器 *.lua|*.txt 必须全部小写
|
||||
* 返 回 值: 1表示在过滤器内, 0表示不在
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint8_t CheckFileNamePostfix(char *_Path, char *_Filter)
|
||||
{
|
||||
char FixName[10];
|
||||
char *p;
|
||||
|
||||
p = GetFileNamePostfix(_Path); /* 获得后缀名,不包括小数点 */
|
||||
strncpy(FixName, p, sizeof(FixName) - 1);
|
||||
|
||||
strlwr(FixName); /* 全部转换为小写字母 */
|
||||
|
||||
p = strstr(_Filter, FixName);
|
||||
if (p > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: FixFileName
|
||||
* 功能说明: 修正文件名中..上级目录. 0:H7-TOOL/User/../Dir1 转换为 0:H7-TOOL/Dir1
|
||||
* 形 参: _Path 文件名
|
||||
* _Filter 过滤器 *.lua|*.txt 必须全部小写
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void FixFileName(char *_Path)
|
||||
{
|
||||
int32_t i,j;
|
||||
int32_t len;
|
||||
|
||||
len = strlen(_Path);
|
||||
|
||||
for (i = 0; i < len - 3; i++)
|
||||
{
|
||||
if (_Path[i] == '/' &&_Path[i + 1] == '.' && _Path[i + 2] == '.')
|
||||
{
|
||||
for (j = i - 1; j > 0; j--)
|
||||
{
|
||||
if (_Path[j] == '/')
|
||||
{
|
||||
strcpy(&_Path[j], &_Path[i + 3]);
|
||||
|
||||
len = strlen(_Path);
|
||||
i = 0; /* 重新开始处理 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -241,7 +860,7 @@ FRESULT OpenFile(FIL* fp, char *_Path)
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void ListDir(char *_Path)
|
||||
void ListDir(char *_Path, char *_Filter)
|
||||
{
|
||||
FRESULT result;
|
||||
uint32_t cnt = 0;
|
||||
@ -276,11 +895,17 @@ void ListDir(char *_Path)
|
||||
/* 判断是文件还是子目录 */
|
||||
if (FileInf.fattrib & AM_DIR)
|
||||
{
|
||||
g_tFileList.Type[g_tFileList.Count] = 0;
|
||||
g_tFileList.Type[g_tFileList.Count] = 0; /* 目录 */
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tFileList.Type[g_tFileList.Count] = 1;
|
||||
g_tFileList.Type[g_tFileList.Count] = 1; /* 文件 */
|
||||
|
||||
/* 过滤掉不符合后缀要求的文件名 */
|
||||
if (CheckFileNamePostfix(FileInf.fname, _Filter) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FILE_NAME_MAX_LEN; i++)
|
||||
@ -298,4 +923,182 @@ void ListDir(char *_Path)
|
||||
f_closedir(&DirInf);
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: SelectFile
|
||||
* 功能说明: l文件浏览器。 用于Lua小程序和脱机编程器
|
||||
* 形 参: _InitPath : 初始路径
|
||||
* _MainStatus : 运行时的状态字
|
||||
* _RetStatus : 返回时的状态字
|
||||
* _Filter : 过滤器,*.lua
|
||||
* 返 回 值: 0 表示返回, 1表示用户按了确认
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint8_t SelectFile(char *_InitPath, uint16_t _MainStatus, uint16_t _RetStatus, char *_Filter)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
uint8_t fRefresh;
|
||||
uint8_t fListDir;
|
||||
uint32_t i;
|
||||
uint8_t RetValue = 0;
|
||||
|
||||
DispHeader("文件浏览器");
|
||||
|
||||
LCD_DispMenu(&g_tMenuLua);
|
||||
|
||||
strcpy(g_tFileList.Path, _InitPath);
|
||||
|
||||
fRefresh = 0;
|
||||
fListDir = 1;
|
||||
while (g_MainStatus == _MainStatus)
|
||||
{
|
||||
if (fRefresh) /* 刷新整个界面 */
|
||||
{
|
||||
fRefresh = 0;
|
||||
|
||||
LCD_ClearMenu(&g_tMenuLua);
|
||||
LCD_DispMenu(&g_tMenuLua);
|
||||
}
|
||||
|
||||
if (fListDir == 1)
|
||||
{
|
||||
fListDir = 0;
|
||||
|
||||
ListDir(g_tFileList.Path, _Filter);
|
||||
|
||||
g_tMenuLua.Left = MENU_LEFT;
|
||||
g_tMenuLua.Top = MENU_TOP;
|
||||
g_tMenuLua.Height = MENU_HEIGHT;
|
||||
g_tMenuLua.Width = MENU_WIDTH;
|
||||
if (g_tParam.FileListFont24 == 1) /* 24点阵显示文件列表 */
|
||||
{
|
||||
g_tMenuLua.LineCap = MENU_CAP;
|
||||
g_tMenuLua.ViewLine = 7;
|
||||
g_tMenuLua.Font.FontCode = FC_ST_24;
|
||||
}
|
||||
else /* 16点阵显示文件列表 */
|
||||
{
|
||||
g_tMenuLua.LineCap = MENU_CAP;
|
||||
g_tMenuLua.ViewLine = 10;
|
||||
g_tMenuLua.Font.FontCode = FC_ST_16;
|
||||
}
|
||||
g_tMenuLua.Font.Space = 0;
|
||||
g_tMenuLua.RollBackEn = 1;
|
||||
g_tMenuLua.GBK = 1;
|
||||
|
||||
for (i = 0; i < g_tFileList.Count; i++)
|
||||
{
|
||||
g_MenuLua_Text[i] = (uint8_t *)g_tFileList.Name[i];
|
||||
}
|
||||
g_MenuLua_Text[i] = "&";
|
||||
|
||||
LCD_InitMenu(&g_tMenuLua, (char **)g_MenuLua_Text); /* 初始化菜单结构 */
|
||||
|
||||
if (g_tFileList.Count >= 2)
|
||||
{
|
||||
g_tMenuLua.Cursor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tMenuLua.Cursor = 0; /* 光标初始位置设置为返回上级 */
|
||||
}
|
||||
|
||||
fRefresh = 1;
|
||||
}
|
||||
|
||||
bsp_Idle();
|
||||
|
||||
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
|
||||
if (ucKeyCode != KEY_NONE)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)
|
||||
{
|
||||
case KEY_UP_S: /* S键 上 */
|
||||
LCD_MoveUpMenu(&g_tMenuLua);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_S: /* S键 长按 */
|
||||
if (g_tMenuLua.Cursor == 0) /* 返回上级 */
|
||||
{
|
||||
uint8_t len;
|
||||
|
||||
/* 0:/H7-TOOL/Lua */
|
||||
len = strlen(g_tFileList.Path);
|
||||
if (strcmp(g_tFileList.Path, _InitPath) == 0) /* 已经在根目录了,退出 */
|
||||
{
|
||||
g_MainStatus = _RetStatus;
|
||||
}
|
||||
else /* 还在子目录 */
|
||||
{
|
||||
for (i = len - 1; i > 2; i--)
|
||||
{
|
||||
if (g_tFileList.Path[i] == '/')
|
||||
{
|
||||
g_tFileList.Path[i] = 0;
|
||||
fListDir = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_tFileList.Type[g_tMenuLua.Cursor] == 0) /* 目录 */
|
||||
{
|
||||
/* 路径后面追加目录 */
|
||||
strcat(g_tFileList.Path, "/");
|
||||
strcat(g_tFileList.Path, g_tFileList.Name[g_tMenuLua.Cursor]);
|
||||
fListDir = 1;
|
||||
}
|
||||
else /* 文件 */
|
||||
{
|
||||
uint16_t len;
|
||||
char *p;
|
||||
char ext_name[5]; /* 扩展名 */
|
||||
|
||||
/* 支持 1.lua, prog.lua */
|
||||
p = g_tFileList.Name[g_tMenuLua.Cursor];
|
||||
len = strlen(p);
|
||||
if (len >= 5)
|
||||
{
|
||||
memcpy(ext_name, &p[len - 4], 4);
|
||||
ext_name[4] = 0;
|
||||
strlwr(ext_name); /* 转换为小写 */
|
||||
if (strcmp(ext_name, ".lua") == 0)
|
||||
{
|
||||
if (_RetStatus == MS_PROG_WORK)
|
||||
{
|
||||
g_MainStatus = MS_PROG_WORK;
|
||||
RetValue = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_MainStatus = MS_LUA_EXEC_FILE;
|
||||
RetValue = 1;
|
||||
}
|
||||
strcat(g_tFileList.Path, "/");
|
||||
strcat(g_tFileList.Path, g_tFileList.Name[g_tMenuLua.Cursor]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP_C: /* C键 下 */
|
||||
LCD_MoveDownMenu(&g_tMenuLua);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_C: /* C键长按 */
|
||||
g_MainStatus = _RetStatus;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "status_tvcc_power.h"
|
||||
#include "status_pulse_meter.h"
|
||||
#include "status_extend_menu.h"
|
||||
#include "status_mini_dso.h"
|
||||
#include "status_lua.h"
|
||||
|
||||
#include "wifi_if.h"
|
||||
@ -46,6 +47,7 @@
|
||||
//#include "usbd_user.h"
|
||||
#include "usb_if.h"
|
||||
#include "file_lib.h"
|
||||
#include "elf_file.h"
|
||||
|
||||
static void DispLogo(void);
|
||||
uint16_t GetStatusIndex(uint16_t _NowStatus);
|
||||
@ -62,7 +64,7 @@ static const uint16_t StatusOrder[] =
|
||||
MS_TEMP_METER, /* 温度表 */
|
||||
MS_TVCC_POWER, /* 微型数控电源 */
|
||||
MS_PULSE_METER, /* 脉冲计 */
|
||||
MS_EXTEND_INIT, /* 扩展菜单 */
|
||||
MS_MINI_DSO, /* 迷你示波器 */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -82,6 +84,20 @@ int main(void)
|
||||
|
||||
DispLogo();
|
||||
|
||||
// /* TEST CRC32 */
|
||||
// {
|
||||
// static uint32_t crc1, crc2, crc3;
|
||||
//
|
||||
// while (1)
|
||||
// {
|
||||
// crc1 = CRC32Software((uint8_t *)0x08000000, 32);
|
||||
// crc2 = STM32_CRC32((uint32_t *)0x08000000, 8);
|
||||
//
|
||||
// crc3 = calculate_CRC32((uint8_t *)0x08000000, 512*1024);
|
||||
// crc2 = STM32_CRC32((uint32_t *)0x08000000, 512*1024 / 4);
|
||||
// }
|
||||
// }
|
||||
|
||||
bsp_InitESP32();
|
||||
|
||||
DSO_InitHard();
|
||||
@ -144,10 +160,18 @@ int main(void)
|
||||
status_FileManage();
|
||||
break;
|
||||
|
||||
case MS_PROG_WORK: /* 脱机下载器 */
|
||||
case MS_PROG_SELECT_FILE: /* 脱机下载器 - 选择文件 */
|
||||
status_ProgSelectFile();
|
||||
break;
|
||||
|
||||
case MS_PROG_WORK: /* 脱机下载器 - 工作阶段 */
|
||||
status_ProgWork();
|
||||
break;
|
||||
break;
|
||||
|
||||
case MS_PROG_SETTING: /* 脱机下载器 - 参数设置 */
|
||||
status_ProgSetting();
|
||||
break;
|
||||
|
||||
case MS_VOLTAGE_METER: /* 电压表 */
|
||||
status_VoltageMeter();
|
||||
break;
|
||||
@ -172,8 +196,8 @@ int main(void)
|
||||
status_PulseMeter();
|
||||
break;
|
||||
|
||||
case MS_EXTEND_INIT: /* 扩展菜单,显示 */
|
||||
status_ExtendInit();
|
||||
case MS_MINI_DSO: /* 扩展菜单,显示 */
|
||||
status_MiniDSO();
|
||||
break;
|
||||
|
||||
case MS_EXTEND_MENU1: /* 扩展菜单,第1级 */
|
||||
@ -401,7 +425,6 @@ void DispHeader2(uint8_t _idx, char *_str)
|
||||
void DispHeaderStr(char *_str)
|
||||
{
|
||||
FONT_T tFont;
|
||||
char buf[48];
|
||||
|
||||
/* 设置字体参数 */
|
||||
{
|
||||
@ -557,6 +580,7 @@ void DispParamBar(uint8_t _ucLine, char *_pName, char *_pValue, uint8_t _ucActiv
|
||||
FONT_T tFont;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t NameWidth;
|
||||
|
||||
/* 设置字体参数 */
|
||||
{
|
||||
@ -583,9 +607,11 @@ void DispParamBar(uint8_t _ucLine, char *_pName, char *_pValue, uint8_t _ucActiv
|
||||
tFont.FrontColor = MEAS_NAME_COLOR;
|
||||
LCD_DispStr(MEAS_WIN_LEFT + 5, y + 4, _pName, &tFont);
|
||||
|
||||
NameWidth = LCD_GetStrWidth(_pName, &tFont);
|
||||
|
||||
/* 测量值 */
|
||||
tFont.FrontColor = MEAS_VALUE_COLOR;
|
||||
LCD_DispStr(MEAS_WIN_LEFT + 120, y + 4, _pValue, &tFont);
|
||||
LCD_DispStr(MEAS_WIN_LEFT + 5 + NameWidth + 5, y + 4, _pValue, &tFont);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -597,14 +623,14 @@ void DispParamBar(uint8_t _ucLine, char *_pName, char *_pValue, uint8_t _ucActiv
|
||||
* _usHeight : 高度
|
||||
* _usWidth : 宽度
|
||||
* _str : 显示文字
|
||||
* _ucPercent : 百分比
|
||||
* _Percent : 百分比, 浮点数
|
||||
* tFont : 字体
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
extern uint8_t s_DispRefresh;
|
||||
void DispProgressBar(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth,
|
||||
char *_str, uint8_t _ucPercent, FONT_T *_tFont)
|
||||
char *_str, float _Percent, FONT_T *_tFont)
|
||||
{
|
||||
uint16_t width;
|
||||
char buf[16];
|
||||
@ -612,14 +638,19 @@ void DispProgressBar(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t
|
||||
uint16_t StrHeight;
|
||||
uint16_t x, y;
|
||||
|
||||
width = ((_usWidth - 4) * _ucPercent) / 100;
|
||||
if (_Percent > 100)
|
||||
{
|
||||
_Percent = 100;
|
||||
}
|
||||
|
||||
width = ((_usWidth - 4) * _Percent) / 100;
|
||||
|
||||
/* 填充矩形 */
|
||||
LCD_DrawRect(_usX, _usY, _usHeight, _usWidth, PROGRESS_BODER_COLOR);
|
||||
|
||||
LCD_Fill_Rect(_usX + 2, _usY + 2, _usHeight - 4, width, PROGRESS_BACK_COLOR1);
|
||||
|
||||
if (_ucPercent < 100)
|
||||
if (_Percent < 100)
|
||||
{
|
||||
LCD_Fill_Rect(_usX + width + 2, _usY + 2, _usHeight - 4, _usWidth - width - 4, PROGRESS_BACK_COLOR2);
|
||||
}
|
||||
@ -628,7 +659,7 @@ void DispProgressBar(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t
|
||||
y = _usY + (_usHeight - StrHeight) / 2;
|
||||
if (_str[0] == 0) /* 居中显示百分比文字 */
|
||||
{
|
||||
sprintf(buf, "%02d%%", _ucPercent);
|
||||
sprintf(buf, "%0.0f%%", _Percent);
|
||||
StrWidth = LCD_GetStrWidth(buf, _tFont);
|
||||
x = _usX + (_usWidth - StrWidth) / 2;
|
||||
LCD_DispStr(x, y, buf, _tFont);
|
||||
|
@ -146,6 +146,8 @@ void InitBaseParam(void)
|
||||
g_tParam.UIStyle = 0;
|
||||
g_tParam.LcdSleepTime = 0; /* 0: 1分钟 1: 5分钟 2 : 15分钟 3: 1小时 4:关闭 */
|
||||
|
||||
g_tParam.FileListFont24 = 0; /* 1表示24点阵显示文件列表,0表示16点阵 */
|
||||
|
||||
SaveParam();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ const uint8_t *g_Menu1_Text[] =
|
||||
" 1 脱机烧录器",
|
||||
" 2 LUA小程序",
|
||||
" 3 数据记录仪",
|
||||
|
||||
" 4 系统设置",
|
||||
/* 结束符号, 用于菜单函数自动识别菜单项个数 */
|
||||
"&"
|
||||
};
|
||||
@ -44,22 +44,23 @@ MENU_T g_tMenuRec;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: status_ExtendInit
|
||||
* 功能说明: 扩展功能菜单,仅显示出来. 长按开始选择
|
||||
* 函 数 名: status_ExtendMenu1
|
||||
* 功能说明: 扩展功能菜单- 第1级
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void status_ExtendInit(void)
|
||||
void status_ExtendMenu1(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
uint8_t fRefresh;
|
||||
static uint8_t s_MenuInit = 0;
|
||||
|
||||
DispHeader("扩展功能");
|
||||
DispHelpBar("长按S开始选择",
|
||||
"长按C:快捷键(上次选择)");
|
||||
|
||||
DispHeader("扩展功能");
|
||||
// DispHelpBar("",
|
||||
// "");
|
||||
|
||||
if (s_MenuInit == 0)
|
||||
{
|
||||
s_MenuInit = 1;
|
||||
@ -75,88 +76,7 @@ void status_ExtendInit(void)
|
||||
g_tMenu1.RollBackEn = 1; /* 允许回滚 */
|
||||
g_tMenu1.GBK = 0;
|
||||
LCD_InitMenu(&g_tMenu1, (char **)g_Menu1_Text); /* 初始化菜单结构 */
|
||||
}
|
||||
LCD_DispMenu2(&g_tMenu1);
|
||||
|
||||
fRefresh = 1;
|
||||
while (g_MainStatus == MS_EXTEND_INIT)
|
||||
{
|
||||
if (fRefresh) /* 刷新整个界面 */
|
||||
{
|
||||
fRefresh = 0;
|
||||
}
|
||||
|
||||
bsp_Idle();
|
||||
|
||||
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
|
||||
if (ucKeyCode != KEY_NONE)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)
|
||||
{
|
||||
case KEY_DOWN_S: /* S键按下 */
|
||||
break;
|
||||
|
||||
case KEY_UP_S: /* S键释放 */
|
||||
g_MainStatus = LastStatus(g_MainStatus);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_S: /* S键长按 */
|
||||
g_MainStatus = MS_EXTEND_MENU1;
|
||||
break;
|
||||
|
||||
case KEY_DOWN_C: /* C键按下 */
|
||||
break;
|
||||
|
||||
case KEY_UP_C: /* C键释放 */
|
||||
g_MainStatus = NextStatus(g_MainStatus);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_C: /* C键长按 - 快捷键 */
|
||||
PlayKeyTone();
|
||||
|
||||
if (g_tMenu1.Cursor == 0)
|
||||
{
|
||||
g_MainStatus = MS_PROG_WORK;
|
||||
}
|
||||
// else if (g_tMenu1.Cursor == 1)
|
||||
// {
|
||||
// g_MainStatus = MS_MODIFY_PARAM;
|
||||
// }
|
||||
// else if (g_tMenu1.Cursor == 2)
|
||||
// {
|
||||
// g_MainStatus = MS_ESP32_TEST;
|
||||
// }
|
||||
// else if (g_tMenu1.Cursor == 3)
|
||||
// {
|
||||
// g_MainStatus = MS_USB_EMMC;
|
||||
// }
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: status_ExtendMenu1
|
||||
* 功能说明: 扩展功能菜单- 第1级
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void status_ExtendMenu1(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
uint8_t fRefresh;
|
||||
|
||||
DispHeader("请选择");
|
||||
DispHelpBar("",
|
||||
"");
|
||||
|
||||
}
|
||||
LCD_DispMenu(&g_tMenu1);
|
||||
|
||||
fRefresh = 1;
|
||||
@ -198,7 +118,11 @@ void status_ExtendMenu1(void)
|
||||
else if (g_tMenu1.Cursor == 2)
|
||||
{
|
||||
g_MainStatus = MS_EXTEND_MENU_REC;
|
||||
}
|
||||
}
|
||||
else if (g_tMenu1.Cursor == 3)
|
||||
{
|
||||
g_MainStatus = MS_SYSTEM_SET;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP_C: /* C键 下 */
|
||||
@ -250,8 +174,8 @@ void status_ExtendMenuRec(void)
|
||||
LCD_DispMenu(&g_tMenuRec);
|
||||
|
||||
DispHeader("请选择");
|
||||
DispHelpBar("",
|
||||
"");
|
||||
// DispHelpBar("",
|
||||
// "");
|
||||
|
||||
LCD_DispMenu(&g_tMenuRec);
|
||||
|
||||
@ -307,7 +231,7 @@ void status_ExtendMenuRec(void)
|
||||
|
||||
case KEY_LONG_DOWN_C: /* C键长按 */
|
||||
PlayKeyTone();
|
||||
g_MainStatus = MS_LINK_MODE;
|
||||
g_MainStatus = MS_EXTEND_MENU1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -54,7 +54,7 @@ void status_LinkMode(void)
|
||||
uint8_t LastMinute = 99;
|
||||
|
||||
DispHeader("联机模式");
|
||||
DispHelpBar("长按S进入系统设置",
|
||||
DispHelpBar("长按S进入扩展功能",
|
||||
"长按C切换方向");
|
||||
|
||||
usbd_CloseCDC();
|
||||
@ -103,7 +103,7 @@ void status_LinkMode(void)
|
||||
|
||||
case KEY_LONG_DOWN_S: /* S键长按 */
|
||||
PlayKeyTone();
|
||||
g_MainStatus = MS_SYSTEM_SET;
|
||||
g_MainStatus = MS_EXTEND_MENU1;
|
||||
break;
|
||||
|
||||
case KEY_DOWN_C: /* C键按下 */
|
||||
|
@ -19,17 +19,6 @@
|
||||
#include "file_lib.h"
|
||||
#include "lua_if.h"
|
||||
|
||||
/* Lua程序根目录 */
|
||||
#define LUA_ROOT_DIR "0:/H7-TOOL/Lua"
|
||||
|
||||
uint8_t *g_MenuLua_Text[FILE_MAX_NUM + 1] =
|
||||
{
|
||||
/* 结束符号, 用于菜单函数自动识别菜单项个数 */
|
||||
"&"
|
||||
};
|
||||
|
||||
MENU_T g_tMenuLua;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: status_LuaSelectFile
|
||||
@ -40,133 +29,7 @@ MENU_T g_tMenuLua;
|
||||
*/
|
||||
void status_LuaSelectFile(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
uint8_t fRefresh;
|
||||
uint8_t fListDir;
|
||||
uint32_t i;
|
||||
|
||||
DispHeader("文件浏览器");
|
||||
|
||||
LCD_DispMenu(&g_tMenuLua);
|
||||
|
||||
strcpy(g_tFileList.Path, LUA_ROOT_DIR);
|
||||
|
||||
fRefresh = 0;
|
||||
fListDir = 1;
|
||||
while (g_MainStatus == MS_LUA_SELECT_FILE)
|
||||
{
|
||||
if (fRefresh) /* 刷新整个界面 */
|
||||
{
|
||||
fRefresh = 0;
|
||||
|
||||
LCD_ClearMenu(&g_tMenuLua);
|
||||
LCD_DispMenu(&g_tMenuLua);
|
||||
}
|
||||
|
||||
if (fListDir == 1)
|
||||
{
|
||||
fListDir = 0;
|
||||
|
||||
ListDir(g_tFileList.Path);
|
||||
|
||||
g_tMenuLua.Left = MENU_LEFT;
|
||||
g_tMenuLua.Top = MENU_TOP;
|
||||
g_tMenuLua.Height = MENU_HEIGHT;
|
||||
g_tMenuLua.Width = MENU_WIDTH;
|
||||
g_tMenuLua.LineCap = MENU_CAP;
|
||||
g_tMenuLua.ViewLine = 7;
|
||||
g_tMenuLua.Font.FontCode = FC_ST_24;
|
||||
g_tMenuLua.Font.Space = 0;
|
||||
g_tMenuLua.RollBackEn = 1;
|
||||
g_tMenuLua.GBK = 1;
|
||||
|
||||
for (i = 0; i < g_tFileList.Count; i++)
|
||||
{
|
||||
g_MenuLua_Text[i] = (uint8_t *)g_tFileList.Name[i];
|
||||
}
|
||||
g_MenuLua_Text[i] = "&";
|
||||
|
||||
LCD_InitMenu(&g_tMenuLua, (char **)g_MenuLua_Text); /* 初始化菜单结构 */
|
||||
|
||||
if (g_tFileList.Count >= 2)
|
||||
{
|
||||
g_tMenuLua.Cursor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tMenuLua.Cursor = 0; /* 光标初始位置设置为返回上级 */
|
||||
}
|
||||
|
||||
fRefresh = 1;
|
||||
}
|
||||
|
||||
bsp_Idle();
|
||||
|
||||
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
|
||||
if (ucKeyCode != KEY_NONE)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)
|
||||
{
|
||||
case KEY_UP_S: /* S键 上 */
|
||||
LCD_MoveUpMenu(&g_tMenuLua);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_S: /* S键 长按 */
|
||||
if (g_tMenuLua.Cursor == 0) /* 返回上级 */
|
||||
{
|
||||
uint8_t len;
|
||||
|
||||
/* 0:/H7-TOOL/Lua */
|
||||
len = strlen(g_tFileList.Path);
|
||||
if (len <= sizeof(LUA_ROOT_DIR)) /* 已经在根目录了,退出 */
|
||||
{
|
||||
g_MainStatus = MS_EXTEND_MENU1;
|
||||
}
|
||||
else /* 还在子目录 */
|
||||
{
|
||||
for (i = len - 1; i > 2; i--)
|
||||
{
|
||||
if (g_tFileList.Path[i] == '/')
|
||||
{
|
||||
g_tFileList.Path[i] = 0;
|
||||
fListDir = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_tFileList.Type[g_tMenuLua.Cursor] == 0) /* 目录 */
|
||||
{
|
||||
/* 路径后面追加目录 */
|
||||
strcat(g_tFileList.Path, "/");
|
||||
strcat(g_tFileList.Path, g_tFileList.Name[g_tMenuLua.Cursor]);
|
||||
fListDir = 1;
|
||||
}
|
||||
else /* 文件 */
|
||||
{
|
||||
strcat(g_tFileList.Path, "/");
|
||||
strcat(g_tFileList.Path, g_tFileList.Name[g_tMenuLua.Cursor]);
|
||||
g_MainStatus = MS_LUA_EXEC_FILE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP_C: /* C键 下 */
|
||||
LCD_MoveDownMenu(&g_tMenuLua);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_C: /* C键长按 */
|
||||
g_MainStatus = MS_LINK_MODE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SelectFile(LUA_ROOT_DIR, MS_LUA_SELECT_FILE, MS_EXTEND_MENU1, "*.lua");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -289,11 +152,10 @@ void FindBtnNoteCmd(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
char g_OutText[2 * 1024] = {0}; /* 最多支持2K字节文本缓存 */
|
||||
MEMO_T g_LuaMemo;
|
||||
MEMO_T g_LuaMemo = {0};
|
||||
void status_LuaRun(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
|
82
User/app/src/status_mini_dso.c
Normal file
82
User/app/src/status_mini_dso.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : 迷你示波器
|
||||
* 文件名称 : status_mini_dso.c
|
||||
* 版 本 : V1.0
|
||||
* 说 明 : 实现迷你示波器
|
||||
* 修改记录 :
|
||||
* 版本号 日期 作者 说明
|
||||
* V1.0 2019-12-14 armfly 正式发布
|
||||
*
|
||||
* Copyright (C), 2018-2030, 安富莱电子 www.armfly.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#include "bsp.h"
|
||||
#include "main.h"
|
||||
#include "lcd_menu.h"
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: status_MiniDSO
|
||||
* 功能说明: 迷你示波器
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void status_MiniDSO(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
uint8_t fRefresh;
|
||||
|
||||
DispHeader("迷你示波器");
|
||||
DispHelpBar("迷你示波器功能预留",
|
||||
"还未实现");
|
||||
|
||||
fRefresh = 1;
|
||||
while (g_MainStatus == MS_MINI_DSO)
|
||||
{
|
||||
if (fRefresh) /* 刷新整个界面 */
|
||||
{
|
||||
fRefresh = 0;
|
||||
}
|
||||
|
||||
bsp_Idle();
|
||||
|
||||
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
|
||||
if (ucKeyCode != KEY_NONE)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)
|
||||
{
|
||||
case KEY_DOWN_S: /* S键按下 */
|
||||
break;
|
||||
|
||||
case KEY_UP_S: /* S键释放 */
|
||||
g_MainStatus = LastStatus(g_MainStatus);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_S: /* S键长按 */
|
||||
;
|
||||
break;
|
||||
|
||||
case KEY_DOWN_C: /* C键按下 */
|
||||
break;
|
||||
|
||||
case KEY_UP_C: /* C键释放 */
|
||||
g_MainStatus = NextStatus(g_MainStatus);
|
||||
break;
|
||||
|
||||
case KEY_LONG_DOWN_C: /* C键长按 - 快捷键 */
|
||||
;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
File diff suppressed because it is too large
Load Diff
@ -135,7 +135,7 @@ void status_SystemSetMain(void)
|
||||
case KEY_LONG_DOWN_C: /* C键长按 */
|
||||
PlayKeyTone();
|
||||
s_enter_sub_menu = 0;
|
||||
g_MainStatus = MS_LINK_MODE;
|
||||
g_MainStatus = MS_EXTEND_MENU1;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -366,7 +366,7 @@ void status_HardInfo(void)
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#define PARAM_NUM 3
|
||||
#define PARAM_NUM 4
|
||||
void status_ModifyParam(void)
|
||||
{
|
||||
uint8_t ucKeyCode; /* 按键代码 */
|
||||
@ -448,6 +448,28 @@ void status_ModifyParam(void)
|
||||
sprintf(buf, "%3d 分钟", min);
|
||||
}
|
||||
DispParamBar(2, "3 屏 保:", buf, active);
|
||||
}
|
||||
|
||||
/* 第3个参数 - 文件列表字体 */
|
||||
{
|
||||
if (cursor == 3)
|
||||
{
|
||||
active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
active = 0;
|
||||
}
|
||||
|
||||
if (g_tParam.FileListFont24 == 1)
|
||||
{
|
||||
sprintf(buf, "24点阵");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf, "16点阵");
|
||||
}
|
||||
DispParamBar(3, "4 列表字体:", buf, active);
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,6 +515,17 @@ void status_ModifyParam(void)
|
||||
{
|
||||
g_tParam.LcdSleepTime = 4;
|
||||
}
|
||||
}
|
||||
else if (cursor == 3)
|
||||
{
|
||||
if (g_tParam.FileListFont24 == 0)
|
||||
{
|
||||
g_tParam.FileListFont24 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tParam.FileListFont24 = 0;
|
||||
}
|
||||
}
|
||||
fRefresh = 1;
|
||||
fSaveParam = 1;
|
||||
@ -527,6 +560,17 @@ void status_ModifyParam(void)
|
||||
{
|
||||
g_tParam.LcdSleepTime = 0;
|
||||
}
|
||||
}
|
||||
else if (cursor == 3)
|
||||
{
|
||||
if (g_tParam.FileListFont24 == 0)
|
||||
{
|
||||
g_tParam.FileListFont24 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_tParam.FileListFont24 = 0;
|
||||
}
|
||||
}
|
||||
fRefresh = 1;
|
||||
fSaveParam = 1;
|
||||
|
@ -318,7 +318,6 @@ static void MPU_Config(void)
|
||||
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
|
||||
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
|
||||
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
|
||||
|
||||
//MPU_InitStruct.Number = MPU_REGION_NUMBER1;
|
||||
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
|
||||
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
|
||||
@ -326,19 +325,20 @@ static void MPU_Config(void)
|
||||
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
|
||||
HAL_MPU_ConfigRegion(&MPU_InitStruct);
|
||||
|
||||
/* 配置总线扩展IO空间的属性为Write through */
|
||||
// MPU_InitStruct.Enable = MPU_REGION_ENABLE;
|
||||
// MPU_InitStruct.BaseAddress = 0x60000000;
|
||||
// MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB; // ARM_MPU_REGION_SIZE_16KB;
|
||||
// MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
|
||||
// MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
|
||||
// MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* 不能用MPU_ACCESS_CACHEABLE;会出现2次CS、WE信号 */
|
||||
// MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
|
||||
// MPU_InitStruct.Number = MPU_REGION_NUMBER3;
|
||||
// MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
|
||||
// MPU_InitStruct.SubRegionDisable = 0x00;
|
||||
// MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
|
||||
// HAL_MPU_ConfigRegion(&MPU_InitStruct);
|
||||
/* 配置显存IO空间的属性为Write through */
|
||||
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
|
||||
MPU_InitStruct.BaseAddress = 0x30000000;
|
||||
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
|
||||
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
|
||||
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
|
||||
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* 不要CASHE */
|
||||
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
|
||||
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
|
||||
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
|
||||
MPU_InitStruct.SubRegionDisable = 0x00;
|
||||
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
|
||||
|
||||
HAL_MPU_ConfigRegion(&MPU_InitStruct);
|
||||
|
||||
/*使能 MPU */
|
||||
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
|
@ -32,12 +32,15 @@ float CaculTwoPointFloat(float x1, float y1, float x2, float y2, float x);
|
||||
|
||||
char BcdToChar(uint8_t _bcd);
|
||||
void HexToAscll(uint8_t *_pHex, char *_pAscii, uint16_t _BinBytes);
|
||||
uint16_t AsciiToHex(char *_pAscii, uint8_t *_pHex, uint16_t _MaxLen);
|
||||
|
||||
uint32_t AsciiToUint32(char *pAscii);
|
||||
|
||||
uint8_t CharToInt(char _ch);
|
||||
uint8_t TwoCharToInt(char *_ch);
|
||||
|
||||
int str_to_int2(char *_pStr);
|
||||
int str_to_int3(char *_pStr);
|
||||
uint8_t ip_str_decode(char *_ipstr, uint8_t *_out);
|
||||
|
||||
uint16_t GetHigh16OfFloat(float _ff);
|
||||
@ -47,6 +50,16 @@ uint8_t float_isnan(float _ff);
|
||||
|
||||
float BEBufToFloat(uint8_t *_pBuf);
|
||||
|
||||
char *strlwr(char *str);
|
||||
char *strupr(char *str);
|
||||
char *StrUTF8ToGBK(char *utf8, char *gbk, uint16_t gbk_size);
|
||||
|
||||
uint8_t CheckBlankBuf(const char *_buf, uint32_t _len, uint8_t _EmptyValue);
|
||||
|
||||
uint32_t STM32_CRC32(uint32_t *_pBuf, uint32_t _Len);
|
||||
uint32_t CRC32Software(uint8_t *pData, uint32_t Length);
|
||||
uint32_t Calculate_CRC32(uint8_t *pStart, uint32_t uSize);
|
||||
|
||||
#endif
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
|
@ -678,23 +678,29 @@ void EIO_D8_Config(EIO_SELECT_E _mode)
|
||||
*/
|
||||
GPIO_InitTypeDef gpio_init;
|
||||
|
||||
GPIO_INIT_OUT_PP(GPIO_D8_DIR, PIN_D8_DIR); /* 配置方向引脚 */
|
||||
GPIO_INIT_OUT_PP(GPIO_D8_DIR, PIN_D8_DIR); /* 配置方向引脚 */
|
||||
|
||||
if (_mode == ES_GPIO_IN)
|
||||
{
|
||||
GPIO_INIT_FMC(GPIOE, GPIO_PIN_11); /* 配置为FMC_D8功能 */
|
||||
GPIO_INIT_FMC(GPIOE, GPIO_PIN_11); /* 配置为FMC_D8功能 */
|
||||
|
||||
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
|
||||
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输入功能 */
|
||||
GPIO_DIR_SET_IN(GPIO_D8_DIR, PIN_D8_DIR); /* 设置为输入方向 - 后执行 */
|
||||
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
|
||||
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输入功能 */
|
||||
GPIO_DIR_SET_IN(GPIO_D8_DIR, PIN_D8_DIR); /* 设置为输入方向 - 后执行 */
|
||||
}
|
||||
else if (_mode == ES_GPIO_OUT)
|
||||
{
|
||||
GPIO_INIT_FMC(GPIOE, GPIO_PIN_11); /* 配置为FMC_D8功能 */
|
||||
GPIO_INIT_FMC(GPIOE, GPIO_PIN_11); /* 配置为FMC_D8功能 */
|
||||
|
||||
GPIO_DIR_SET_OUT(GPIO_D8_DIR, PIN_D8_DIR); /* 设置为输出方向 - 先执行 */
|
||||
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
|
||||
GPIO_INIT_OUT_PP(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
|
||||
GPIO_DIR_SET_OUT(GPIO_D8_DIR, PIN_D8_DIR); /* 设置为输出方向 - 先执行 */
|
||||
|
||||
#if 0
|
||||
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
|
||||
GPIO_INIT_OUT_PP(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
|
||||
#else /* FOR 软件SWD优化 */
|
||||
GPIO_INIT_OUT_PP(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
|
||||
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
|
||||
#endif
|
||||
}
|
||||
else if (_mode == ES_FMC_OUT)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ static __IO uint8_t CmdCplt, RxCplt, TxCplt, StatusMatch, TimeOut;
|
||||
static void QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi);
|
||||
static void QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi);
|
||||
|
||||
static void QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
|
||||
//static void QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
|
||||
|
||||
uint8_t QSPI_MemoryMapped(void);
|
||||
|
||||
@ -603,90 +603,90 @@ uint32_t QSPI_ReadID(void)
|
||||
* @param hqspi: QSPI handle
|
||||
* @retval None
|
||||
*/
|
||||
static void QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
|
||||
{
|
||||
QSPI_CommandTypeDef s_command;
|
||||
uint16_t reg=0;
|
||||
//static void QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
|
||||
//{
|
||||
// QSPI_CommandTypeDef s_command;
|
||||
// uint16_t reg=0;
|
||||
|
||||
/* Initialize the read volatile configuration register command */
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
s_command.Instruction = READ_VOL_CFG_REG_CMD;
|
||||
s_command.AddressMode = QSPI_ADDRESS_NONE;
|
||||
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
s_command.DataMode = QSPI_DATA_1_LINE;
|
||||
s_command.DummyCycles = 0;
|
||||
s_command.NbData = 2;
|
||||
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
|
||||
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
|
||||
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
// /* Initialize the read volatile configuration register command */
|
||||
// s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
// s_command.Instruction = READ_VOL_CFG_REG_CMD;
|
||||
// s_command.AddressMode = QSPI_ADDRESS_NONE;
|
||||
// s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
// s_command.DataMode = QSPI_DATA_1_LINE;
|
||||
// s_command.DummyCycles = 0;
|
||||
// s_command.NbData = 2;
|
||||
// s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
|
||||
// s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
|
||||
// s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
/* Configure the command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);;
|
||||
}
|
||||
// /* Configure the command */
|
||||
// if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler(__FILE__, __LINE__);;
|
||||
// }
|
||||
|
||||
/* Reception of the data */
|
||||
if (HAL_QSPI_Receive(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);;
|
||||
}
|
||||
// /* Reception of the data */
|
||||
// if (HAL_QSPI_Receive(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler(__FILE__, __LINE__);;
|
||||
// }
|
||||
|
||||
/* Enable write operations */
|
||||
QSPI_WriteEnable(hqspi);
|
||||
// /* Enable write operations */
|
||||
// QSPI_WriteEnable(hqspi);
|
||||
|
||||
/* Update volatile configuration register (with new dummy cycles) */
|
||||
s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
|
||||
MODIFY_REG(reg, 0xF0F0, ((DUMMY_CLOCK_CYCLES_READ_QUAD << 4) |
|
||||
(DUMMY_CLOCK_CYCLES_READ_QUAD << 12)));
|
||||
// /* Update volatile configuration register (with new dummy cycles) */
|
||||
// s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
|
||||
// MODIFY_REG(reg, 0xF0F0, ((DUMMY_CLOCK_CYCLES_READ_QUAD << 4) |
|
||||
// (DUMMY_CLOCK_CYCLES_READ_QUAD << 12)));
|
||||
|
||||
/* Configure the write volatile configuration register command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);;
|
||||
}
|
||||
// /* Configure the write volatile configuration register command */
|
||||
// if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler(__FILE__, __LINE__);;
|
||||
// }
|
||||
|
||||
/* Transmission of the data */
|
||||
if (HAL_QSPI_Transmit(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);;
|
||||
}
|
||||
// /* Transmission of the data */
|
||||
// if (HAL_QSPI_Transmit(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler(__FILE__, __LINE__);;
|
||||
// }
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief This function set the QSPI memory in 4-byte address mode
|
||||
* @param hqspi: QSPI handle
|
||||
* @retval None
|
||||
*/
|
||||
static void QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
|
||||
{
|
||||
QSPI_CommandTypeDef s_command;
|
||||
//static void QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
|
||||
//{
|
||||
// QSPI_CommandTypeDef s_command;
|
||||
|
||||
/* Initialize the command */
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
s_command.Instruction = ENTER_4_BYTE_ADDR_MODE_CMD;
|
||||
s_command.AddressMode = QSPI_ADDRESS_NONE;
|
||||
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
s_command.DataMode = QSPI_DATA_NONE;
|
||||
s_command.DummyCycles = 0;
|
||||
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
|
||||
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
|
||||
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
// /* Initialize the command */
|
||||
// s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
// s_command.Instruction = ENTER_4_BYTE_ADDR_MODE_CMD;
|
||||
// s_command.AddressMode = QSPI_ADDRESS_NONE;
|
||||
// s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
// s_command.DataMode = QSPI_DATA_NONE;
|
||||
// s_command.DummyCycles = 0;
|
||||
// s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
|
||||
// s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
|
||||
// s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
/* Enable write operations */
|
||||
QSPI_WriteEnable(hqspi);
|
||||
|
||||
/* Send the command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);;
|
||||
}
|
||||
// /* Enable write operations */
|
||||
// QSPI_WriteEnable(hqspi);
|
||||
//
|
||||
// /* Send the command */
|
||||
// if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler(__FILE__, __LINE__);;
|
||||
// }
|
||||
|
||||
/* Configure automatic polling mode to wait the memory is ready */
|
||||
QSPI_AutoPollingMemReady(hqspi);
|
||||
// /* Configure automatic polling mode to wait the memory is ready */
|
||||
// QSPI_AutoPollingMemReady(hqspi);
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
|
@ -3,9 +3,8 @@
|
||||
*
|
||||
* 模块名称 : TFT液晶显示器驱动模块
|
||||
* 文件名称 : bsp_tft_lcd.c
|
||||
* 版 本 : V4.2
|
||||
* 说 明 : 支持3.0, 3.5, 4.3, 5.0, 7.0寸显示模块.
|
||||
* 3.0寸的支持的LCD内部驱动芯片型号有: SPFD5420A、OTM4001A、R61509V
|
||||
* 版 本 : V5.1
|
||||
* 说 明 : H7-TOOL 1.3寸屏专用
|
||||
* 修改记录 :
|
||||
* 版本号 日期 作者 说明
|
||||
* v1.0 2011-08-21 armfly ST固件库版本 V3.5.0版本。
|
||||
@ -50,6 +49,8 @@
|
||||
* - LCD_GetStrWidth() 函数更新。
|
||||
* - 显示字符串函数限制超出宽度 LCD_DispStrEx0()
|
||||
* - \t字符串中的\t划线指令更换为\v指令. 避免和Lua print的\t冲突
|
||||
* V5.1 2019-12-29
|
||||
* - 解决LCD_DrawMemo bug, Text==0时禁止显示
|
||||
*
|
||||
* Copyright (C), 2015-2030, 安富莱电子 www.armfly.com
|
||||
*
|
||||
@ -159,20 +160,25 @@ uint8_t LCD_GetEncode(void)
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
extern uint32_t wTransferState;
|
||||
void LCD_Task(void)
|
||||
{
|
||||
if (g_LcdSleepReq == 1) /* 进入休眠。按键中断服务程序中会设置1 */
|
||||
/* 在DMA SPI传输完毕后才能设置LCD休眠 */
|
||||
if (wTransferState == 1)
|
||||
{
|
||||
g_LcdSleepReq = 0;
|
||||
LCD_DispOff(); /* 该函数会操作SPI,不可以在中断服务程序中执行 */
|
||||
}
|
||||
else if (g_LcdSleepReq == 2) /* 退出休眠。按键中断服务程序中会设置2 */
|
||||
{
|
||||
g_LcdSleepReq = 0;
|
||||
LCD_DispOn(); /* 该函数会操作SPI,不可以在中断服务程序中执行 */
|
||||
if (g_LcdSleepReq == 1) /* 进入休眠。按键中断服务程序中会设置1 */
|
||||
{
|
||||
g_LcdSleepReq = 0;
|
||||
LCD_DispOff(); /* 该函数会操作SPI,不可以在中断服务程序中执行 */
|
||||
}
|
||||
else if (g_LcdSleepReq == 2) /* 退出休眠。按键中断服务程序中会设置2 */
|
||||
{
|
||||
g_LcdSleepReq = 0;
|
||||
LCD_DispOn(); /* 该函数会操作SPI,不可以在中断服务程序中执行 */
|
||||
}
|
||||
}
|
||||
|
||||
ST7789_DrawScreen(); /* 硬件SPI+DMA+刷屏 */
|
||||
ST7789_DrawScreen(); /* 硬件SPI+DMA+刷屏 */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3280,6 +3286,11 @@ void LCD_DrawMemo(MEMO_T *_pMemo)
|
||||
|
||||
_pMemo->Refresh = 0;
|
||||
|
||||
if (_pMemo->Text == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 绘制边框,填充窗口 */
|
||||
LCD_DrawRect(_pMemo->Left, _pMemo->Top, _pMemo->Height, _pMemo->Width, EDIT_BORDER_COLOR);
|
||||
LCD_Fill_Rect(_pMemo->Left + 1, _pMemo->Top + 1, _pMemo->Height - 2, _pMemo->Width - 2, EDIT_BACK_COLOR);
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "fonts.h"
|
||||
#include "param.h"
|
||||
|
||||
#define LCD_DMA_CIRCULE_MODE 0
|
||||
|
||||
/*
|
||||
H7-TOOL LCD口线分配
|
||||
----- 第6版 -----
|
||||
@ -112,7 +114,7 @@ static void ST7789_SendByteQuick(uint8_t data);
|
||||
|
||||
SPI_HandleTypeDef hspi5 = {0};
|
||||
DMA_HandleTypeDef hdma_tx = {0};
|
||||
__IO uint32_t wTransferState = 0;
|
||||
__IO uint32_t wTransferState = 99;
|
||||
|
||||
static uint16_t *s_pDispBuf;
|
||||
static uint8_t s_DispRefresh = 0;
|
||||
@ -184,7 +186,13 @@ void bsp_InitSPI5ParamFast(void)
|
||||
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_tx.Init.Mode = DMA_NORMAL;
|
||||
|
||||
#if LCD_DMA_CIRCULE_MODE == 1
|
||||
hdma_tx.Init.Mode = DMA_CIRCULAR;
|
||||
#else
|
||||
hdma_tx.Init.Mode = DMA_NORMAL;
|
||||
#endif
|
||||
|
||||
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
|
||||
HAL_DMA_Init(&hdma_tx);
|
||||
@ -238,6 +246,8 @@ void bsp_InitSPI5_Fast(void)
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
wTransferState = 1;
|
||||
|
||||
LCD_CS_1();
|
||||
}
|
||||
|
||||
void DMA2_Stream3_IRQHandler(void)
|
||||
@ -303,26 +313,55 @@ static void ST7789_ConfigGPIO(void)
|
||||
*/
|
||||
void ST7789_DrawScreen(void)
|
||||
{
|
||||
#if LCD_DMA_CIRCULE_MODE == 1
|
||||
static uint8_t first_run = 1;
|
||||
|
||||
if (first_run == 1)
|
||||
{
|
||||
first_run = 0;
|
||||
|
||||
ST7789_SetDispWin(0, 0, 240, 240);
|
||||
|
||||
bsp_InitSPI5ParamFast();
|
||||
LCD_RS_1();
|
||||
LCD_CS_0();
|
||||
|
||||
wTransferState = 0;
|
||||
// SCB_CleanInvalidateDCache();
|
||||
|
||||
HAL_SPI_Transmit_DMA(&hspi5, (uint8_t *)(0x30000000), 240 * 240);
|
||||
}
|
||||
#else
|
||||
static int32_t s_time1 = 0;
|
||||
|
||||
if (s_DispRefresh == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 控制刷屏周期,限制最快50ms */
|
||||
if (bsp_CheckRunTime(s_time1) < 50)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* 放到前面判断 */
|
||||
while (wTransferState == 0){}
|
||||
|
||||
s_DispRefresh = 0;
|
||||
|
||||
ST7789_SetDispWin(0, 0, 240, 240);
|
||||
|
||||
bsp_InitSPI5ParamFast();
|
||||
LCD_RS_1();
|
||||
LCD_CS_0();
|
||||
LCD_CS_0(); /* 在DMA传输完毕后设置1 */
|
||||
|
||||
wTransferState = 0;
|
||||
SCB_CleanInvalidateDCache();
|
||||
|
||||
|
||||
HAL_SPI_Transmit_DMA(&hspi5, (uint8_t *)(0x30000000), 240 * 240);
|
||||
while (wTransferState == 0){}
|
||||
|
||||
LCD_CS_1();
|
||||
|
||||
s_time1 = bsp_GetRunTime();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*写指令到 LCD 模块*/
|
||||
@ -673,7 +712,20 @@ void ST7789_QuitWinMode(void)
|
||||
*/
|
||||
void ST7789_DispOn(void)
|
||||
{
|
||||
#if LCD_DMA_CIRCULE_MODE == 1
|
||||
LCD_CS_1();
|
||||
Lcd_WriteIndex(0x11);
|
||||
|
||||
ST7789_SetDispWin(0, 0, 240, 240);
|
||||
|
||||
bsp_InitSPI5ParamFast();
|
||||
LCD_RS_1();
|
||||
LCD_CS_0();
|
||||
|
||||
HAL_SPI_Transmit_DMA(&hspi5, (uint8_t *)(0x30000000), 240 * 240);
|
||||
#else
|
||||
Lcd_WriteIndex(0x11);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -686,7 +738,14 @@ void ST7789_DispOn(void)
|
||||
*/
|
||||
void ST7789_DispOff(void)
|
||||
{
|
||||
#if LCD_DMA_CIRCULE_MODE == 1
|
||||
LCD_CS_1();
|
||||
Lcd_WriteIndex(0x10);
|
||||
|
||||
HAL_SPI_Abort(&hspi5);
|
||||
#else
|
||||
Lcd_WriteIndex(0x10);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -722,8 +781,14 @@ void ST7789_ClrScr(uint16_t _usColor)
|
||||
*/
|
||||
void ST7789_PutPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor)
|
||||
{
|
||||
#if 1
|
||||
s_pDispBuf[_usY * 240 + _usX] = _usColor;
|
||||
#if 1
|
||||
uint32_t idx;
|
||||
|
||||
idx = _usY * 240 + _usX;
|
||||
if (idx < 240 * 240 * 2)
|
||||
{
|
||||
s_pDispBuf[idx] = _usColor;
|
||||
}
|
||||
#else
|
||||
ST7789_SetDispWin(_usX, _usY, 1, 1);
|
||||
Lcd_WriteData_16(_usColor);
|
||||
@ -958,10 +1023,22 @@ void ST7789_FillRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t
|
||||
{
|
||||
#if 1
|
||||
uint16_t i, j;
|
||||
uint16_t width, height;
|
||||
|
||||
for (i = 0; i < _usWidth; i++)
|
||||
width = _usWidth;
|
||||
height = _usHeight;
|
||||
if (height > g_LcdHeight)
|
||||
{
|
||||
for (j = 0; j < _usHeight; j++)
|
||||
height = g_LcdHeight;
|
||||
}
|
||||
if (width > g_LcdWidth)
|
||||
{
|
||||
width = g_LcdWidth;
|
||||
}
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
ST7789_PutPixel(_usX + i, _usY + j, _usColor);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
// CRC 高位字节值表
|
||||
static const uint8_t s_CRCHi[] = {
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
|
||||
@ -72,7 +74,186 @@ const uint8_t s_CRCLo[] = {
|
||||
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
|
||||
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
|
||||
0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
|
||||
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
|
||||
};
|
||||
|
||||
uint32_t Crc32Table[256]=
|
||||
{
|
||||
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
|
||||
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD,
|
||||
0x4C11DB70,0x48D0C6C7,0x4593E01E,0x4152FDA9,0x5F15ADAC,0x5BD4B01B,0x569796C2,0x52568B75,
|
||||
0x6A1936C8,0x6ED82B7F,0x639B0DA6,0x675A1011,0x791D4014,0x7DDC5DA3,0x709F7B7A,0x745E66CD,
|
||||
0x9823B6E0,0x9CE2AB57,0x91A18D8E,0x95609039,0x8B27C03C,0x8FE6DD8B,0x82A5FB52,0x8664E6E5,
|
||||
0xBE2B5B58,0xBAEA46EF,0xB7A96036,0xB3687D81,0xAD2F2D84,0xA9EE3033,0xA4AD16EA,0xA06C0B5D,
|
||||
0xD4326D90,0xD0F37027,0xDDB056FE,0xD9714B49,0xC7361B4C,0xC3F706FB,0xCEB42022,0xCA753D95,
|
||||
0xF23A8028,0xF6FB9D9F,0xFBB8BB46,0xFF79A6F1,0xE13EF6F4,0xE5FFEB43,0xE8BCCD9A,0xEC7DD02D,
|
||||
0x34867077,0x30476DC0,0x3D044B19,0x39C556AE,0x278206AB,0x23431B1C,0x2E003DC5,0x2AC12072,
|
||||
0x128E9DCF,0x164F8078,0x1B0CA6A1,0x1FCDBB16,0x018AEB13,0x054BF6A4,0x0808D07D,0x0CC9CDCA,
|
||||
0x7897AB07,0x7C56B6B0,0x71159069,0x75D48DDE,0x6B93DDDB,0x6F52C06C,0x6211E6B5,0x66D0FB02,
|
||||
0x5E9F46BF,0x5A5E5B08,0x571D7DD1,0x53DC6066,0x4D9B3063,0x495A2DD4,0x44190B0D,0x40D816BA,
|
||||
0xACA5C697,0xA864DB20,0xA527FDF9,0xA1E6E04E,0xBFA1B04B,0xBB60ADFC,0xB6238B25,0xB2E29692,
|
||||
0x8AAD2B2F,0x8E6C3698,0x832F1041,0x87EE0DF6,0x99A95DF3,0x9D684044,0x902B669D,0x94EA7B2A,
|
||||
0xE0B41DE7,0xE4750050,0xE9362689,0xEDF73B3E,0xF3B06B3B,0xF771768C,0xFA325055,0xFEF34DE2,
|
||||
0xC6BCF05F,0xC27DEDE8,0xCF3ECB31,0xCBFFD686,0xD5B88683,0xD1799B34,0xDC3ABDED,0xD8FBA05A,
|
||||
0x690CE0EE,0x6DCDFD59,0x608EDB80,0x644FC637,0x7A089632,0x7EC98B85,0x738AAD5C,0x774BB0EB,
|
||||
0x4F040D56,0x4BC510E1,0x46863638,0x42472B8F,0x5C007B8A,0x58C1663D,0x558240E4,0x51435D53,
|
||||
0x251D3B9E,0x21DC2629,0x2C9F00F0,0x285E1D47,0x36194D42,0x32D850F5,0x3F9B762C,0x3B5A6B9B,
|
||||
0x0315D626,0x07D4CB91,0x0A97ED48,0x0E56F0FF,0x1011A0FA,0x14D0BD4D,0x19939B94,0x1D528623,
|
||||
0xF12F560E,0xF5EE4BB9,0xF8AD6D60,0xFC6C70D7,0xE22B20D2,0xE6EA3D65,0xEBA91BBC,0xEF68060B,
|
||||
0xD727BBB6,0xD3E6A601,0xDEA580D8,0xDA649D6F,0xC423CD6A,0xC0E2D0DD,0xCDA1F604,0xC960EBB3,
|
||||
0xBD3E8D7E,0xB9FF90C9,0xB4BCB610,0xB07DABA7,0xAE3AFBA2,0xAAFBE615,0xA7B8C0CC,0xA379DD7B,
|
||||
0x9B3660C6,0x9FF77D71,0x92B45BA8,0x9675461F,0x8832161A,0x8CF30BAD,0x81B02D74,0x857130C3,
|
||||
0x5D8A9099,0x594B8D2E,0x5408ABF7,0x50C9B640,0x4E8EE645,0x4A4FFBF2,0x470CDD2B,0x43CDC09C,
|
||||
0x7B827D21,0x7F436096,0x7200464F,0x76C15BF8,0x68860BFD,0x6C47164A,0x61043093,0x65C52D24,
|
||||
0x119B4BE9,0x155A565E,0x18197087,0x1CD86D30,0x029F3D35,0x065E2082,0x0B1D065B,0x0FDC1BEC,
|
||||
0x3793A651,0x3352BBE6,0x3E119D3F,0x3AD08088,0x2497D08D,0x2056CD3A,0x2D15EBE3,0x29D4F654,
|
||||
0xC5A92679,0xC1683BCE,0xCC2B1D17,0xC8EA00A0,0xD6AD50A5,0xD26C4D12,0xDF2F6BCB,0xDBEE767C,
|
||||
0xE3A1CBC1,0xE760D676,0xEA23F0AF,0xEEE2ED18,0xF0A5BD1D,0xF464A0AA,0xF9278673,0xFDE69BC4,
|
||||
0x89B8FD09,0x8D79E0BE,0x803AC667,0x84FBDBD0,0x9ABC8BD5,0x9E7D9662,0x933EB0BB,0x97FFAD0C,
|
||||
0xAFB010B1,0xAB710D06,0xA6322BDF,0xA2F33668,0xBCB4666D,0xB8757BDA,0xB5365D03,0xB1F740B4
|
||||
};
|
||||
|
||||
//查表法
|
||||
uint32_t CRC32Software(uint8_t *pData, uint32_t Length)
|
||||
{
|
||||
uint32_t nReg;//CRC寄存器
|
||||
uint32_t nTemp=0;
|
||||
uint16_t i, n;
|
||||
|
||||
nReg = 0xFFFFFFFF;
|
||||
for (n = 0; n < Length; n++)
|
||||
{
|
||||
nReg ^= (uint32_t)pData[n];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
nTemp = Crc32Table[(uint8_t)(( nReg >> 24 ) & 0xff)]; //取一个字节,查表
|
||||
nReg <<= 8; //丢掉计算过的头一个BYTE
|
||||
nReg ^= nTemp; //与前一个BYTE的计算结果异或
|
||||
}
|
||||
}
|
||||
return nReg;
|
||||
}
|
||||
|
||||
/* STM32的CRC */
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: STM32_CRC32
|
||||
* 功能说明: 计算字符串长度.0是结束符
|
||||
* 形 参: _pBuf : 缓冲区. 32bit对齐
|
||||
* _Len : 字节长度
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint32_t STM32_CRC32(uint32_t *_pBuf, uint32_t _Len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
__HAL_RCC_CRC_CLK_ENABLE();
|
||||
|
||||
CRC->CR |= CRC_CR_RESET;
|
||||
for (i = 0; i < _Len / 4; i++)
|
||||
{
|
||||
CRC->DR = *_pBuf++;
|
||||
}
|
||||
return (CRC->DR);
|
||||
}
|
||||
|
||||
static const uint32_t crc32c_table[256] = {
|
||||
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
|
||||
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
|
||||
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
|
||||
0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
|
||||
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
|
||||
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
|
||||
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
|
||||
0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
|
||||
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
|
||||
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
|
||||
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
|
||||
0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
|
||||
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
|
||||
0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
|
||||
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
|
||||
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
|
||||
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
|
||||
0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
|
||||
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
|
||||
0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
|
||||
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
|
||||
0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
|
||||
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
|
||||
0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
|
||||
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
|
||||
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
|
||||
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
|
||||
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
|
||||
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
|
||||
0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
|
||||
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
|
||||
0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
|
||||
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
|
||||
0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
|
||||
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
|
||||
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
|
||||
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
|
||||
0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
|
||||
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
|
||||
0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
|
||||
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
|
||||
0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
|
||||
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
|
||||
0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
|
||||
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
|
||||
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
|
||||
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
|
||||
0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
|
||||
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
|
||||
0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
|
||||
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
|
||||
0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
|
||||
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
|
||||
0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
|
||||
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
|
||||
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
|
||||
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
|
||||
0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
|
||||
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
|
||||
0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
|
||||
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
|
||||
0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
|
||||
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
|
||||
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
||||
};
|
||||
|
||||
//uint32_t crc32c(uint32_t crc, const uint8_t *data, uint32_t length)
|
||||
//{
|
||||
// while (length--)
|
||||
// crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
|
||||
//
|
||||
// return crc;
|
||||
//}
|
||||
|
||||
uint32_t Calculate_CRC32 (uint8_t *pStart, uint32_t uSize)
|
||||
{
|
||||
#define INIT 0xffffffffL
|
||||
#define XOROT 0xffffffffL
|
||||
|
||||
uint32_t uCRCValue;
|
||||
uint8_t *pData;
|
||||
|
||||
uCRCValue = INIT;
|
||||
pData = pStart;
|
||||
|
||||
while (uSize--)
|
||||
{
|
||||
uCRCValue = crc32c_table[(uCRCValue ^ *pData++) & 0xFFL] ^ (uCRCValue >> 8);
|
||||
}
|
||||
|
||||
return uCRCValue ^ XOROT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
@ -424,6 +605,61 @@ void HexToAscll(uint8_t *_pHex, char *_pAscii, uint16_t _BinBytes)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: AsciiToHex
|
||||
* 功能说明: 将ASCII字符串转换为 二进制数组。自动过滤空格。
|
||||
* "FF 12 34 F0" 转化为 0xFF,0x12,0x34,0xF0
|
||||
* 形 参: _pAscii :存放转换结果, ASCII字符串,0结束。1个二进制对应2个ASCII字符.
|
||||
* _pHex :输入的数据,二进制数组
|
||||
* _MaxLen : _pHex 数组最大长度
|
||||
* 返 回 值: 转换数组长度.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint16_t AsciiToHex(char *_pAscii, uint8_t *_pHex, uint16_t _MaxLen)
|
||||
{
|
||||
uint32_t hexlen;
|
||||
char buf[2];
|
||||
char idx = 0;
|
||||
char ch;
|
||||
|
||||
hexlen = 0;
|
||||
while (*_pAscii != 0)
|
||||
{
|
||||
ch = *_pAscii;
|
||||
if (ch == ' ' || ch == '\t')
|
||||
{
|
||||
_pAscii++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((ch >= 'A') && (ch <= 'F')) ||
|
||||
((ch >= 'a') && (ch <= 'f')) ||
|
||||
((ch >= '0') && (ch <= '9')))
|
||||
{
|
||||
buf[idx++] = *_pAscii++;
|
||||
if (idx == 2)
|
||||
{
|
||||
_pHex[hexlen++] = TwoCharToInt(buf);
|
||||
|
||||
if (hexlen == _MaxLen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hexlen = 0; /* 格式错误,返回0 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hexlen;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: AsciiToUint32
|
||||
@ -586,8 +822,8 @@ uint8_t TwoCharToInt(char *_ch)
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: str_to_int
|
||||
* 功能说明: 将ASCII码字符串转换成整数。 遇到小数点也结束
|
||||
* 函 数 名: str_to_int2
|
||||
* 功能说明: 将ASCII码字符串转换成整数。 遇到非0-9的字符结束。数字前面不能有空格。
|
||||
* 形 参: _pStr :待转换的ASCII码串. 可以以逗号,#或0结束。 2014-06-20 修改为非0-9的字符。
|
||||
* 返 回 值: 二进制整数值
|
||||
*********************************************************************************************************
|
||||
@ -634,7 +870,78 @@ int str_to_int2(char *_pStr)
|
||||
return ulInt;
|
||||
}
|
||||
|
||||
/* 带小数点的IP字符串,转换为4字节数组 */
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: str_to_int3
|
||||
* 功能说明: 将ASCII码字符串转换成整数 (用于ini文件)。 遇到空格和TAB自动略过,遇到小数点和非0-9字符结束
|
||||
* 形 参: _pStr :待转换的ASCII码串,前面可以有空格和tab,结束是非0-9字符。
|
||||
* 返 回 值: 二进制整数值
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
int str_to_int3(char *_pStr)
|
||||
{
|
||||
unsigned char state = 0;
|
||||
unsigned char flag = 0;
|
||||
char *p;
|
||||
int ulInt;
|
||||
unsigned char ucTemp;
|
||||
|
||||
p = _pStr;
|
||||
|
||||
ulInt = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ucTemp = *p++;
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
if (ucTemp == ' ' || ucTemp == '\t')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ucTemp == '-')
|
||||
{
|
||||
flag = 1; /* 是负数 */
|
||||
}
|
||||
else
|
||||
{
|
||||
ulInt = ulInt * 10 + (ucTemp - '0');
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
if ((ucTemp >= '0') && (ucTemp <= '9'))
|
||||
{
|
||||
ulInt = ulInt * 10 + (ucTemp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag == 1)
|
||||
{
|
||||
return -ulInt;
|
||||
}
|
||||
return ulInt;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ip_str_decode
|
||||
* 功能说明: 带小数点的IP字符串,转换为4字节数组
|
||||
* 形 参: _ipstr :待转换的ASCII码串
|
||||
* _out : 存放结果二进制整数值
|
||||
* 返 回 值: 1表示OK, 0表示格式错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint8_t ip_str_decode(char *_ipstr, uint8_t *_out)
|
||||
{
|
||||
char *p;
|
||||
@ -804,4 +1111,180 @@ void FloatToBEBuf(float _f, uint8_t *_pBuf)
|
||||
_pBuf[3] = p[0];
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: strlwr
|
||||
* 功能说明: 将字符串转换为小写. 需要 #include <ctype.h>
|
||||
* 形 参: str 字符串
|
||||
* 返 回 值: 字符串
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
char *strlwr(char *str)
|
||||
{
|
||||
char *orign = str;
|
||||
|
||||
for (; *str != 0; str++)
|
||||
{
|
||||
*str = tolower(*str);
|
||||
}
|
||||
return orign;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: strupr
|
||||
* 功能说明: 将字符串转换为大写. 需要 #include <ctype.h>
|
||||
* 形 参: str 字符串
|
||||
* 返 回 值: 字符串
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
char *strupr(char *str)
|
||||
{
|
||||
char *orign = str;
|
||||
|
||||
for (; *str!= 0; str++)
|
||||
{
|
||||
*str = toupper(*str);
|
||||
}
|
||||
return orign;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: StrUTF8ToGBK
|
||||
* 功能说明: 将UTF8字符串转换GBK字符串
|
||||
* 形 参: utf8 输入字符串
|
||||
* gbk 输出字符串
|
||||
* gbk_size 字符串size
|
||||
* 返 回 值: 字符串
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
char *StrUTF8ToGBK(char *utf8, char *gbk, uint16_t gbk_size)
|
||||
{
|
||||
uint8_t code1, code2;
|
||||
char *_ptr;
|
||||
char *_pOut;
|
||||
uint16_t len = 0;
|
||||
|
||||
_ptr = utf8;
|
||||
_pOut = gbk;
|
||||
|
||||
/* 开始循环处理字符 */
|
||||
while (*_ptr != 0)
|
||||
{
|
||||
code1 = *_ptr; /* 读取字符串数据, 该数据可能是ascii代码,也可能汉字代码的高字节 */
|
||||
if (code1 < 0x80)
|
||||
{
|
||||
if (len + 1 < gbk_size)
|
||||
{
|
||||
*_pOut++ = code1;
|
||||
|
||||
len++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 解读 UTF-8 编码非常简单。
|
||||
如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
|
||||
UNICODE 最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0
|
||||
|
||||
110XXXXX 10XXXXXX -- 支持
|
||||
1110XXXX 10XXXXXX 10XXXXXX -- 支持
|
||||
11110XXX 10XXXXXX 10XXXXXX 10XXXXXX -- 本转换程序不支持
|
||||
*/
|
||||
{
|
||||
uint8_t code3;
|
||||
uint32_t unicode1;
|
||||
uint16_t gb;
|
||||
|
||||
if ((code1 & 0xE0) == 0xC0) /* 2字节 */
|
||||
{
|
||||
code2 = *++_ptr;
|
||||
if (code2 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
unicode1 = ((uint32_t)(code1 & 0x1F) << 6) + (code2 & 0x3F);
|
||||
}
|
||||
else if ((code1 & 0xF0) == 0xE0) /* 3字节 */
|
||||
{
|
||||
code2 = *++_ptr;
|
||||
code3 = *++_ptr;
|
||||
if (code2 == 0 || code3 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
unicode1 = ((uint32_t)(code1 & 0x0F) << 12) + ((uint32_t)(code2 & 0x3F) << 6) + (code3 & 0x3F);
|
||||
}
|
||||
else if ((code1 & 0xF8) == 0xF0) /* 4字节 */
|
||||
{
|
||||
code2 = *++_ptr;
|
||||
if (code2 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
code2 = *++_ptr;
|
||||
if (code2 == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 将UNICODE码转换为GB2312 */
|
||||
if (unicode1 > 0xFFFF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
gb = ff_convert(unicode1, 0); /* Unicode -> OEM */
|
||||
|
||||
code1 = gb >> 8;
|
||||
code2 = gb;
|
||||
|
||||
if (len + 2 < gbk_size)
|
||||
{
|
||||
*_pOut++ = code1;
|
||||
*_pOut++ = code2;
|
||||
|
||||
len += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ptr++;
|
||||
}
|
||||
|
||||
*_pOut = 0;
|
||||
|
||||
return gbk;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: CheckBlankBuf
|
||||
* 功能说明: 检查一个缓冲区的数值是否空(空值判定有给定的参数_EmptyValue决定)
|
||||
* 形 参: _buf 数据缓冲区
|
||||
* _len : 数据字节数
|
||||
* _EmptyValue : 空值,一般为0xFF 或者0x00
|
||||
* 返 回 值: 1表示是空,0表示不空
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint8_t CheckBlankBuf(const char *_buf, uint32_t _len, uint8_t _EmptyValue)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < _len; i++)
|
||||
{
|
||||
if (_buf[i] != _EmptyValue)
|
||||
{
|
||||
return 0; /* 不空 */
|
||||
}
|
||||
}
|
||||
|
||||
return 1; /* 缓冲区为空 */
|
||||
}
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file DAP.c
|
||||
* @brief Implementation of DAP.h
|
||||
*
|
||||
@ -1601,7 +1601,7 @@ void DAP_Setup(void) {
|
||||
|
||||
// Default settings
|
||||
DAP_Data.debug_port = 0U;
|
||||
DAP_Data.fast_clock = 1U;
|
||||
DAP_Data.fast_clock = 1U; // ARMFLY
|
||||
DAP_Data.clock_delay = CLOCK_DELAY(DAP_DEFAULT_SWJ_CLOCK);
|
||||
DAP_Data.transfer.idle_cycles = 0U;
|
||||
DAP_Data.transfer.retry_count = 100U;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file DAP.h
|
||||
* @brief Access to ARM DAP using CMSIS-DAP protocol
|
||||
*
|
||||
@ -244,6 +244,10 @@ extern uint32_t DAP_ExecuteCommand (const uint8_t *request, uint8_t *respo
|
||||
|
||||
extern void DAP_Setup (void);
|
||||
|
||||
extern uint32_t g_SwdSpiBaud;
|
||||
|
||||
#define SWD_SPI_BAUD(x) g_SwdSpiBaud = x
|
||||
|
||||
// Configurable delay for clock generation
|
||||
#ifndef DELAY_SLOW_CYCLES
|
||||
#define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration
|
||||
@ -252,7 +256,7 @@ static __forceinline void PIN_DELAY_SLOW (uint32_t delay) {
|
||||
uint32_t count;
|
||||
|
||||
count = delay;
|
||||
while (--count);
|
||||
while (count--);
|
||||
}
|
||||
|
||||
// Fixed delay for fast clock generation
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
|
||||
#define SPI_MODE_ENABLE 1 /* 1 表示SPI模式, 0表示GPIO模式 */
|
||||
|
||||
|
||||
/*
|
||||
SPI_BAUDRATEPRESCALER_4 = 50MHz SCK时钟,不能工作。
|
||||
@ -45,207 +45,104 @@
|
||||
实测ST-LINK下载640K程序,擦除需要9秒(这是CPU的FLASH擦除时间较慢导致),编程和校验需要13秒。
|
||||
按H7-TOOL的800KB/S的速度,SWD时序传输可以在1秒内完成,剩下的时间主要靠USB通信和CPU运算来提高效率。
|
||||
因此在SWD底层时序上优化已经没有多大的必要了,也许可以提高到1MB/S。但是对整体效率没有多大改善。
|
||||
|
||||
|
||||
SPI_BAUDRATEPRESCALER_32 : 稳定读写 STM32F030RCT6
|
||||
*/
|
||||
#define SPI_MODE_BAUD SPI_BAUDRATEPRESCALER_8 /* SPI_BAUDRATEPRESCALER_4 不稳定 */
|
||||
#define SPI_MODE_BAUD g_SwdSpiBaud /* SPI_BAUDRATEPRESCALER_4 不稳定 */
|
||||
|
||||
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
|
||||
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
|
||||
|
||||
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
|
||||
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
|
||||
|
||||
#define SW_CLOCK_CYCLE() \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define SW_WRITE_BIT(bit) \
|
||||
PIN_SWDIO_OUT(bit); \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define SW_READ_BIT(bit) \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
bit = PIN_SWDIO_IN(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
|
||||
/* SPI软件模式,低速配置 */
|
||||
#define PIN_DELAY_S() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
#define SW_CLOCK_CYCLE_SLOW() PIN_SWCLK_CLR(); PIN_DELAY_S(); PIN_SWCLK_SET(); PIN_DELAY_S()
|
||||
#define SW_WRITE_BIT_SLOW(bit) PIN_SWDIO_OUT(bit); PIN_SWCLK_CLR(); PIN_DELAY_S(); PIN_SWCLK_SET(); PIN_DELAY_S()
|
||||
#define SW_READ_BIT_SLOW(bit) PIN_SWCLK_CLR(); PIN_DELAY_S(); bit = PIN_SWDIO_IN(); PIN_SWCLK_SET(); PIN_DELAY_S()
|
||||
|
||||
/* SPI软件模式,高速配置 */
|
||||
#define SW_CLOCK_CYCLE_FAST() PIN_SWCLK_CLR(); PIN_SWCLK_SET();
|
||||
#if 0 /* 优化GPIO操作 */
|
||||
#define SW_WRITE_BIT_FAST(bit) \
|
||||
if (bit & 1) \
|
||||
{ \
|
||||
GPIOD->BSRR = GPIO_PIN_4 + (GPIO_PIN_3 << 16U); \
|
||||
PIN_SWCLK_SET(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
GPIOD->BSRR = (GPIO_PIN_4 + GPIO_PIN_3) << 16U; \
|
||||
PIN_SWCLK_SET(); \
|
||||
}
|
||||
#else
|
||||
#define SW_WRITE_BIT_FAST(bit) PIN_SWDIO_OUT(bit); PIN_SWCLK_CLR(); PIN_SWCLK_SET();
|
||||
#endif
|
||||
|
||||
#define SW_READ_BIT_FAST(bit) PIN_SWCLK_CLR(); bit = PIN_SWDIO_IN(); PIN_SWCLK_SET();
|
||||
|
||||
#if (DAP_SWD != 0)
|
||||
|
||||
uint32_t g_SwdSpiBaud = SPI_BAUDRATEPRESCALER_32;
|
||||
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#define SWD_TransferFunction(speed) /**/ \
|
||||
uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
|
||||
uint32_t ack; \
|
||||
uint32_t bit; \
|
||||
uint32_t val; \
|
||||
uint32_t parity; \
|
||||
\
|
||||
uint32_t n; \
|
||||
\
|
||||
/* Packet Request */ \
|
||||
parity = 0U; \
|
||||
SW_WRITE_BIT(1U); /* Start Bit */ \
|
||||
bit = request >> 0; \
|
||||
SW_WRITE_BIT(bit); /* APnDP Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 1; \
|
||||
SW_WRITE_BIT(bit); /* RnW Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 2; \
|
||||
SW_WRITE_BIT(bit); /* A2 Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 3; \
|
||||
SW_WRITE_BIT(bit); /* A3 Bit */ \
|
||||
parity += bit; \
|
||||
SW_WRITE_BIT(parity); /* Parity Bit */ \
|
||||
SW_WRITE_BIT(0U); /* Stop Bit */ \
|
||||
SW_WRITE_BIT(1U); /* Park Bit */ \
|
||||
\
|
||||
/* Turnaround */ \
|
||||
PIN_SWDIO_OUT_DISABLE(); \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
\
|
||||
/* Acknowledge response */ \
|
||||
SW_READ_BIT(bit); \
|
||||
ack = bit << 0; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 1; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 2; \
|
||||
\
|
||||
if (ack == DAP_TRANSFER_OK) { /* OK response */ \
|
||||
/* Data transfer */ \
|
||||
if (request & DAP_TRANSFER_RnW) { \
|
||||
/* Read data */ \
|
||||
val = 0U; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
|
||||
parity += bit; \
|
||||
val >>= 1; \
|
||||
val |= bit << 31; \
|
||||
} \
|
||||
SW_READ_BIT(bit); /* Read Parity */ \
|
||||
if ((parity ^ bit) & 1U) { \
|
||||
ack = DAP_TRANSFER_ERROR; \
|
||||
} \
|
||||
if (data) { *data = val; } \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
} else { \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
/* Write data */ \
|
||||
val = *data; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
|
||||
parity += val; \
|
||||
val >>= 1; \
|
||||
} \
|
||||
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
|
||||
} \
|
||||
/* Idle cycles */ \
|
||||
n = DAP_Data.transfer.idle_cycles; \
|
||||
if (n) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
} \
|
||||
\
|
||||
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
|
||||
/* WAIT or FAULT response */ \
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
|
||||
for (n = 32U+1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
|
||||
} \
|
||||
} \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (n = 32U+1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
} \
|
||||
\
|
||||
/* Protocol error */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Back off data phase */ \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
}
|
||||
#if 1 /* 优化 PD3 PD4 同步操作节省30ns */
|
||||
|
||||
//#define SWCLK_TCK_PIN_PORT GPIOD
|
||||
//#define SWCLK_TCK_PIN GPIO_PIN_3
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_FAST()
|
||||
SWD_TransferFunction(Fast);
|
||||
//#define SWDIO_OUT_PIN_PORT GPIOD
|
||||
//#define SWDIO_OUT_PIN GPIO_PIN_4
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
SWD_TransferFunction(Slow);
|
||||
//#define BSP_SET_GPIO_1(gpio, pin) gpio->BSRR = pin
|
||||
//#define BSP_SET_GPIO_0(gpio, pin) gpio->BSRR = (uint32_t)pin << 16U
|
||||
|
||||
|
||||
uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data);
|
||||
uint8_t SWD_TransferFastH7_ok(uint32_t request, uint32_t *data);
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
uint8_t SWD_Transfer(uint32_t request, uint32_t *data)
|
||||
#define SEND_32BIT_ONCE() \
|
||||
if (val & 1) \
|
||||
{ \
|
||||
GPIOD->BSRR = GPIO_PIN_4 + (GPIO_PIN_3 << 16U); \
|
||||
val >>= 1; \
|
||||
PIN_SWCLK_SET(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
GPIOD->BSRR = (GPIO_PIN_4 + GPIO_PIN_3) << 16U; \
|
||||
val >>= 1; \
|
||||
PIN_SWCLK_SET(); \
|
||||
}
|
||||
#else /* 未优化 */
|
||||
#define SEND_32BIT_ONCE() \
|
||||
if (val & 1) \
|
||||
{ \
|
||||
BSP_SET_GPIO_1(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
BSP_SET_GPIO_0(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN); \
|
||||
} \
|
||||
PIN_SWCLK_CLR(); \
|
||||
val >>= 1; \
|
||||
PIN_SWCLK_SET();
|
||||
#endif
|
||||
|
||||
static const uint8_t ParityTable256[256] =
|
||||
{
|
||||
if (DAP_Data.fast_clock)
|
||||
{
|
||||
//return SWD_TransferFast(request, data);
|
||||
return SWD_TransferFastH7(request, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SWD_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* armfly 优化时序速度 ***************************/
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_FAST()
|
||||
# define P2(n) n, n^1, n^1, n
|
||||
# define P4(n) P2(n), P2(n^1), P2(n^1), P2(n)
|
||||
# define P6(n) P4(n), P4(n^1), P4(n^1), P4(n)
|
||||
P6(0), P6(1), P6(1), P6(0)
|
||||
};
|
||||
|
||||
uint8_t GetParity(uint32_t data)
|
||||
{
|
||||
#if 1
|
||||
uint8_t parity;
|
||||
|
||||
data ^= data >> 16;
|
||||
data ^= data >> 8;
|
||||
|
||||
parity = ParityTable256[data & 0xff];
|
||||
|
||||
return parity;
|
||||
#else
|
||||
uint8_t parity = 0;
|
||||
|
||||
parity = (data >> 31) + (data >> 30) + (data >> 29) + (data >> 28)
|
||||
@ -267,8 +164,443 @@ uint8_t GetParity(uint32_t data)
|
||||
}
|
||||
|
||||
return parity;
|
||||
#endif
|
||||
}
|
||||
|
||||
//// SWD Transfer I/O
|
||||
//// request: A[3:2] RnW APnDP
|
||||
//// data: DATA[31:0]
|
||||
//// return: ACK[2:0]
|
||||
//#define SWD_TransferFunction(speed) /**/ \
|
||||
//uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
|
||||
// uint32_t ack; \
|
||||
// uint32_t bit; \
|
||||
// uint32_t val; \
|
||||
// uint32_t parity; \
|
||||
// \
|
||||
// uint32_t n; \
|
||||
// \
|
||||
// /* Packet Request */ \
|
||||
// parity = 0U; \
|
||||
// SW_WRITE_BIT(1U); /* Start Bit */ \
|
||||
// bit = request >> 0; \
|
||||
// SW_WRITE_BIT(bit); /* APnDP Bit */ \
|
||||
// parity += bit; \
|
||||
// bit = request >> 1; \
|
||||
// SW_WRITE_BIT(bit); /* RnW Bit */ \
|
||||
// parity += bit; \
|
||||
// bit = request >> 2; \
|
||||
// SW_WRITE_BIT(bit); /* A2 Bit */ \
|
||||
// parity += bit; \
|
||||
// bit = request >> 3; \
|
||||
// SW_WRITE_BIT(bit); /* A3 Bit */ \
|
||||
// parity += bit; \
|
||||
// SW_WRITE_BIT(parity); /* Parity Bit */ \
|
||||
// SW_WRITE_BIT(0U); /* Stop Bit */ \
|
||||
// SW_WRITE_BIT(1U); /* Park Bit */ \
|
||||
// \
|
||||
// /* Turnaround */ \
|
||||
// PIN_SWDIO_OUT_DISABLE(); \
|
||||
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); \
|
||||
// } \
|
||||
// \
|
||||
// /* Acknowledge response */ \
|
||||
// SW_READ_BIT(bit); \
|
||||
// ack = bit << 0; \
|
||||
// SW_READ_BIT(bit); \
|
||||
// ack |= bit << 1; \
|
||||
// SW_READ_BIT(bit); \
|
||||
// ack |= bit << 2; \
|
||||
// \
|
||||
// if (ack == DAP_TRANSFER_OK) { /* OK response */ \
|
||||
// /* Data transfer */ \
|
||||
// if (request & DAP_TRANSFER_RnW) { \
|
||||
// /* Read data */ \
|
||||
// val = 0U; \
|
||||
// parity = 0U; \
|
||||
// for (n = 32U; n; n--) { \
|
||||
// SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
|
||||
// parity += bit; \
|
||||
// val >>= 1; \
|
||||
// val |= bit << 31; \
|
||||
// } \
|
||||
// SW_READ_BIT(bit); /* Read Parity */ \
|
||||
// if ((parity ^ bit) & 1U) { \
|
||||
// ack = DAP_TRANSFER_ERROR; \
|
||||
// } \
|
||||
// if (data) { *data = val; } \
|
||||
// /* Turnaround */ \
|
||||
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT_ENABLE(); \
|
||||
// } else { \
|
||||
// /* Turnaround */ \
|
||||
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT_ENABLE(); \
|
||||
// /* Write data */ \
|
||||
// val = *data; \
|
||||
// parity = 0U; \
|
||||
// for (n = 32U; n; n--) { \
|
||||
// SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
|
||||
// parity += val; \
|
||||
// val >>= 1; \
|
||||
// } \
|
||||
// SW_WRITE_BIT(parity); /* Write Parity Bit */ \
|
||||
// } \
|
||||
// /* Idle cycles */ \
|
||||
// n = DAP_Data.transfer.idle_cycles; \
|
||||
// if (n) { \
|
||||
// PIN_SWDIO_OUT(0U); \
|
||||
// for (; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); \
|
||||
// } \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT(1U); \
|
||||
// return ((uint8_t)ack); \
|
||||
// } \
|
||||
// \
|
||||
// if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
|
||||
// /* WAIT or FAULT response */ \
|
||||
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
|
||||
// for (n = 32U+1U; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
|
||||
// } \
|
||||
// } \
|
||||
// /* Turnaround */ \
|
||||
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT_ENABLE(); \
|
||||
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
|
||||
// PIN_SWDIO_OUT(0U); \
|
||||
// for (n = 32U+1U; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
|
||||
// } \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT(1U); \
|
||||
// return ((uint8_t)ack); \
|
||||
// } \
|
||||
// \
|
||||
// /* Protocol error */ \
|
||||
// for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
|
||||
// SW_CLOCK_CYCLE(); /* Back off data phase */ \
|
||||
// } \
|
||||
// PIN_SWDIO_OUT_ENABLE(); \
|
||||
// PIN_SWDIO_OUT(1U); \
|
||||
// return ((uint8_t)ack); \
|
||||
//}
|
||||
|
||||
uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
|
||||
{
|
||||
uint32_t ack;
|
||||
uint32_t bit;
|
||||
uint32_t val;
|
||||
uint32_t parity;
|
||||
|
||||
uint32_t n;
|
||||
|
||||
/* Packet Request */
|
||||
parity = 0U;
|
||||
SW_WRITE_BIT_FAST(1U); /* Start Bit */
|
||||
bit = request >> 0;
|
||||
SW_WRITE_BIT_FAST(bit); /* APnDP Bit */
|
||||
parity += bit;
|
||||
bit = request >> 1;
|
||||
SW_WRITE_BIT_FAST(bit); /* RnW Bit */
|
||||
parity += bit;
|
||||
bit = request >> 2;
|
||||
SW_WRITE_BIT_FAST(bit); /* A2 Bit */
|
||||
parity += bit;
|
||||
bit = request >> 3;
|
||||
SW_WRITE_BIT_FAST(bit); /* A3 Bit */
|
||||
parity += bit;
|
||||
SW_WRITE_BIT_FAST(parity); /* Parity Bit */
|
||||
SW_WRITE_BIT_FAST(0U); /* Stop Bit */
|
||||
SW_WRITE_BIT_FAST(1U); /* Park Bit */
|
||||
|
||||
/* Turnaround */
|
||||
PIN_SWDIO_OUT_DISABLE();
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
|
||||
/* Acknowledge response */
|
||||
SW_READ_BIT_FAST(bit);
|
||||
ack = bit << 0;
|
||||
SW_READ_BIT_FAST(bit);
|
||||
ack |= bit << 1;
|
||||
SW_READ_BIT_FAST(bit);
|
||||
ack |= bit << 2;
|
||||
|
||||
if (ack == DAP_TRANSFER_OK) { /* OK response */
|
||||
/* Data transfer */
|
||||
if (request & DAP_TRANSFER_RnW) {
|
||||
/* Read data */
|
||||
#if 1 /* armfly : 优化奇偶校验算法 */
|
||||
val = 0U;
|
||||
for (n = 32U; n; n--) {
|
||||
SW_READ_BIT_FAST(bit); /* Read RDATA[0:31] */
|
||||
val >>= 1;
|
||||
val |= bit << 31;
|
||||
}
|
||||
|
||||
parity = GetParity(val);
|
||||
#else
|
||||
val = 0U;
|
||||
parity = 0U;
|
||||
|
||||
for (n = 32U; n; n--) {
|
||||
SW_READ_BIT_FAST(bit); /* Read RDATA[0:31] */
|
||||
parity += bit;
|
||||
val >>= 1;
|
||||
val |= bit << 31;
|
||||
}
|
||||
#endif
|
||||
|
||||
SW_READ_BIT_FAST(bit); /* Read Parity */
|
||||
if ((parity ^ bit) & 1U) {
|
||||
ack = DAP_TRANSFER_ERROR;
|
||||
}
|
||||
if (data) { *data = val; }
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
} else {
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
/* Write data */
|
||||
val = *data;
|
||||
|
||||
#if 1 /* armfly : 优化奇偶校验算法 */
|
||||
// parity = GetParity(val);
|
||||
// for (n = 32U; n; n--) {
|
||||
// SW_WRITE_BIT_FAST(val); /* Write WDATA[0:31] */
|
||||
// val >>= 1;
|
||||
// }
|
||||
|
||||
parity = GetParity(val);
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
|
||||
#else
|
||||
parity = 0U;
|
||||
for (n = 32U; n; n--) {
|
||||
SW_WRITE_BIT_FAST(val); /* Write WDATA[0:31] */
|
||||
parity += val;
|
||||
val >>= 1;
|
||||
}
|
||||
#endif
|
||||
SW_WRITE_BIT_FAST(parity); /* Write Parity Bit */
|
||||
}
|
||||
/* Idle cycles */
|
||||
n = DAP_Data.transfer.idle_cycles;
|
||||
if (n) {
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
|
||||
/* WAIT or FAULT response */
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) {
|
||||
for (n = 32U+1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST(); /* Dummy Read RDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) {
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (n = 32U+1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST(); /* Dummy Write WDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
/* Protocol error */
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_FAST(); /* Back off data phase */
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
uint8_t SWD_TransferSlow(uint32_t request, uint32_t *data)
|
||||
{
|
||||
uint32_t ack;
|
||||
uint32_t bit;
|
||||
uint32_t val;
|
||||
uint32_t parity;
|
||||
|
||||
uint32_t n;
|
||||
|
||||
/* Packet Request */
|
||||
parity = 0U;
|
||||
SW_WRITE_BIT_SLOW(1U); /* Start Bit */
|
||||
bit = request >> 0;
|
||||
SW_WRITE_BIT_SLOW(bit); /* APnDP Bit */
|
||||
parity += bit;
|
||||
bit = request >> 1;
|
||||
SW_WRITE_BIT_SLOW(bit); /* RnW Bit */
|
||||
parity += bit;
|
||||
bit = request >> 2;
|
||||
SW_WRITE_BIT_SLOW(bit); /* A2 Bit */
|
||||
parity += bit;
|
||||
bit = request >> 3;
|
||||
SW_WRITE_BIT_SLOW(bit); /* A3 Bit */
|
||||
parity += bit;
|
||||
SW_WRITE_BIT_SLOW(parity); /* Parity Bit */
|
||||
SW_WRITE_BIT_SLOW(0U); /* Stop Bit */
|
||||
SW_WRITE_BIT_SLOW(1U); /* Park Bit */
|
||||
|
||||
/* Turnaround */
|
||||
PIN_SWDIO_OUT_DISABLE();
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
}
|
||||
|
||||
/* Acknowledge response */
|
||||
SW_READ_BIT_SLOW(bit);
|
||||
ack = bit << 0;
|
||||
SW_READ_BIT_SLOW(bit);
|
||||
ack |= bit << 1;
|
||||
SW_READ_BIT_SLOW(bit);
|
||||
ack |= bit << 2;
|
||||
|
||||
if (ack == DAP_TRANSFER_OK) { /* OK response */
|
||||
/* Data transfer */
|
||||
if (request & DAP_TRANSFER_RnW) {
|
||||
/* Read data */
|
||||
val = 0U;
|
||||
parity = 0U;
|
||||
for (n = 32U; n; n--) {
|
||||
SW_READ_BIT_SLOW(bit); /* Read RDATA[0:31] */
|
||||
parity += bit;
|
||||
val >>= 1;
|
||||
val |= bit << 31;
|
||||
}
|
||||
SW_READ_BIT_SLOW(bit); /* Read Parity */
|
||||
if ((parity ^ bit) & 1U) {
|
||||
ack = DAP_TRANSFER_ERROR;
|
||||
}
|
||||
if (data) { *data = val; }
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
} else {
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
/* Write data */
|
||||
val = *data;
|
||||
parity = 0U;
|
||||
for (n = 32U; n; n--) {
|
||||
SW_WRITE_BIT_SLOW(val); /* Write WDATA[0:31] */
|
||||
parity += val;
|
||||
val >>= 1;
|
||||
}
|
||||
SW_WRITE_BIT_SLOW(parity); /* Write Parity Bit */
|
||||
}
|
||||
/* Idle cycles */
|
||||
n = DAP_Data.transfer.idle_cycles;
|
||||
if (n) {
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
|
||||
/* WAIT or FAULT response */
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) {
|
||||
for (n = 32U+1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW(); /* Dummy Read RDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) {
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (n = 32U+1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW(); /* Dummy Write WDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
/* Protocol error */
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) {
|
||||
SW_CLOCK_CYCLE_SLOW(); /* Back off data phase */
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data);
|
||||
uint8_t SWD_Transfer(uint32_t request, uint32_t *data)
|
||||
{
|
||||
if (DAP_Data.fast_clock)
|
||||
{
|
||||
#if SPI_MODE_ENABLE == 1
|
||||
return SWD_TransferFastH7(request, data);
|
||||
#else
|
||||
return SWD_TransferFast(request, data);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return SWD_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* armfly 优化时序速度 ***************************/
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_FAST()
|
||||
|
||||
void SWD_SendBits(uint8_t _bits, uint32_t _data)
|
||||
{
|
||||
#if SPI_MODE_ENABLE == 1
|
||||
@ -316,7 +648,7 @@ void SWD_SendBits(uint8_t _bits, uint32_t _data)
|
||||
|
||||
for (i = 0; i < _bits; i++)
|
||||
{
|
||||
SW_WRITE_BIT(_data >> i);
|
||||
SW_WRITE_BIT_SLOW(_data >> i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -373,7 +705,7 @@ uint32_t SWD_ReadBits(uint8_t _bits)
|
||||
|
||||
_bits--;
|
||||
|
||||
EIO_SetOutLevel(2, 1);
|
||||
// EIO_SetOutLevel(2, 1); 测试波形用
|
||||
|
||||
SPI2->CFG1 = SPI_MODE_BAUD | _bits;
|
||||
// SPI2->CR1 = SPI_CR1_SSI ;
|
||||
@ -403,7 +735,7 @@ uint32_t SWD_ReadBits(uint8_t _bits)
|
||||
ret = SPI2->RXDR;
|
||||
SPI2->CR1 &= ~(SPI_CR1_SPE);
|
||||
|
||||
EIO_SetOutLevel(2, 0);
|
||||
// EIO_SetOutLevel(2, 0); 测试波形用
|
||||
return ret;
|
||||
|
||||
#else
|
||||
@ -413,7 +745,7 @@ uint32_t SWD_ReadBits(uint8_t _bits)
|
||||
|
||||
for (i = 0; i < _bits; i++)
|
||||
{
|
||||
SW_READ_BIT(bit); /* Read RDATA[0:31] */
|
||||
SW_READ_BIT_SLOW(bit); /* Read RDATA[0:31] */
|
||||
val >>= 1;
|
||||
val |= bit << (_bits - 1);
|
||||
}
|
||||
@ -493,7 +825,7 @@ void SWJ_Sequence (uint32_t count, const uint8_t *data) {
|
||||
} else {
|
||||
PIN_SWDIO_TMS_CLR();
|
||||
}
|
||||
SW_CLOCK_CYCLE();
|
||||
SW_CLOCK_CYCLE_SLOW();
|
||||
val >>= 1;
|
||||
n--;
|
||||
}
|
||||
@ -618,7 +950,7 @@ uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data)
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
SW_CLOCK_CYCLE_FAST();
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
@ -758,147 +1090,4 @@ uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data)
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
uint8_t SWD_TransferFastH7_ok(uint32_t request, uint32_t *data)
|
||||
{
|
||||
uint32_t ack;
|
||||
uint32_t bit;
|
||||
uint32_t val;
|
||||
uint32_t parity;
|
||||
|
||||
uint32_t n;
|
||||
|
||||
/* Packet Request */
|
||||
parity = 0U;
|
||||
SW_WRITE_BIT(1U); /* Start Bit */
|
||||
bit = request >> 0;
|
||||
SW_WRITE_BIT(bit); /* APnDP Bit */
|
||||
parity += bit;
|
||||
bit = request >> 1;
|
||||
SW_WRITE_BIT(bit); /* RnW Bit */
|
||||
parity += bit;
|
||||
bit = request >> 2;
|
||||
SW_WRITE_BIT(bit); /* A2 Bit */
|
||||
parity += bit;
|
||||
bit = request >> 3;
|
||||
SW_WRITE_BIT(bit); /* A3 Bit */
|
||||
parity += bit;
|
||||
SW_WRITE_BIT(parity); /* Parity Bit */
|
||||
SW_WRITE_BIT(0U); /* Stop Bit */
|
||||
SW_WRITE_BIT(1U); /* Park Bit */
|
||||
|
||||
/* Turnaround */
|
||||
PIN_SWDIO_OUT_DISABLE();
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
}
|
||||
|
||||
/* Acknowledge response */
|
||||
SW_READ_BIT(bit);
|
||||
ack = bit << 0;
|
||||
SW_READ_BIT(bit);
|
||||
ack |= bit << 1;
|
||||
SW_READ_BIT(bit);
|
||||
ack |= bit << 2;
|
||||
|
||||
if (ack == DAP_TRANSFER_OK)
|
||||
{ /* OK response */
|
||||
/* Data transfer */
|
||||
if (request & DAP_TRANSFER_RnW) /* 读指令 - 32 + 1 bit */
|
||||
{
|
||||
/* Read data */
|
||||
val = 0U;
|
||||
parity = 0U;
|
||||
for (n = 32U; n; n--)
|
||||
{
|
||||
SW_READ_BIT(bit); /* Read RDATA[0:31] */
|
||||
parity += bit;
|
||||
val >>= 1;
|
||||
val |= bit << 31;
|
||||
}
|
||||
SW_READ_BIT(bit); /* Read Parity */
|
||||
if ((parity ^ bit) & 1U)
|
||||
{
|
||||
ack = DAP_TRANSFER_ERROR;
|
||||
}
|
||||
if (data) { *data = val; }
|
||||
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
/* Write data */
|
||||
val = *data;
|
||||
parity = 0U;
|
||||
for (n = 32U; n; n--)
|
||||
{
|
||||
SW_WRITE_BIT(val); /* Write WDATA[0:31] */
|
||||
parity += val;
|
||||
val >>= 1;
|
||||
}
|
||||
SW_WRITE_BIT(parity); /* Write Parity Bit */
|
||||
}
|
||||
/* Idle cycles */
|
||||
n = DAP_Data.transfer.idle_cycles;
|
||||
if (n)
|
||||
{
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT))
|
||||
{
|
||||
/* WAIT or FAULT response */
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U))
|
||||
{
|
||||
for (n = 32U+1U; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
/* Turnaround */
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE();
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))
|
||||
{
|
||||
PIN_SWDIO_OUT(0U);
|
||||
for (n = 32U+1U; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */
|
||||
}
|
||||
}
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
/* Protocol error */
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--)
|
||||
{
|
||||
SW_CLOCK_CYCLE(); /* Back off data phase */
|
||||
}
|
||||
PIN_SWDIO_OUT_ENABLE();
|
||||
PIN_SWDIO_OUT(1U);
|
||||
return ((uint8_t)ack);
|
||||
}
|
||||
|
||||
#endif /* (DAP_SWD != 0) */
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
#include "target_family.h"
|
||||
#include "prog_if.h"
|
||||
#include "file_lib.h"
|
||||
|
||||
// Default NVIC and Core debug base addresses
|
||||
// TODO: Read these addresses from ROM.
|
||||
@ -530,11 +532,11 @@ uint8_t swd_read_memory(uint32_t address, uint8_t *data, uint32_t size)
|
||||
uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t n = 0;
|
||||
|
||||
|
||||
// Write bytes until word aligned
|
||||
while ((size > 0) && (address & 0x3)) {
|
||||
if (!swd_write_byte(address, *data)) {
|
||||
return 0;
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
address++;
|
||||
@ -552,7 +554,7 @@ uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size)
|
||||
}
|
||||
|
||||
if (!swd_write_block(address, data, n)) {
|
||||
return 0;
|
||||
goto err_quit;;
|
||||
}
|
||||
|
||||
address += n;
|
||||
@ -563,15 +565,17 @@ uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size)
|
||||
// Write remaining bytes
|
||||
while (size > 0) {
|
||||
if (!swd_write_byte(address, *data)) {
|
||||
return 0;
|
||||
goto err_quit;
|
||||
}
|
||||
|
||||
address++;
|
||||
data++;
|
||||
size--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err_quit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute system call.
|
||||
@ -683,8 +687,76 @@ uint8_t swd_write_core_register(uint32_t n, uint32_t val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: swd_wait_until_halted
|
||||
* 功能说明: 执行FLM中的函数,等待完成. 增加了超时控制,全局变量 g_tProg.FLMFuncTimeout
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
extern void PG_PrintPercent(float _Percent);
|
||||
extern uint8_t ProgCancelKey(void);
|
||||
static uint8_t swd_wait_until_halted(void)
|
||||
{
|
||||
#if 1
|
||||
// Wait for target to stop
|
||||
uint32_t val;
|
||||
int32_t time1;
|
||||
|
||||
time1 = bsp_GetRunTime();
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* 擦除芯片 */
|
||||
if (g_tProg.FLMEraseChipFlag == 1)
|
||||
{
|
||||
if (g_tProgIni.LastEraseChipTime == 0)
|
||||
{
|
||||
g_tProgIni.LastEraseChipTime = 20000; /* 第1次缺省按20秒计算进度 */
|
||||
}
|
||||
|
||||
/* 整片擦除 */
|
||||
{
|
||||
int32_t tt;
|
||||
float percent;
|
||||
|
||||
tt = bsp_CheckRunTime(time1);
|
||||
if (tt > g_tProg.FLMFuncTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tt % 250) == 0)
|
||||
{
|
||||
percent = ((float)tt / g_tProgIni.LastEraseChipTime) * 100;
|
||||
PG_PrintPercent(percent);
|
||||
}
|
||||
bsp_Idle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!swd_read_word(DBG_HCSR, &val))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (val & S_HALT)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ProgCancelKey())
|
||||
{
|
||||
PG_PrintText("用户终止运行");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
// Wait for target to stop
|
||||
uint32_t val, i, timeout = MAX_TIMEOUT;
|
||||
|
||||
@ -699,6 +771,7 @@ static uint8_t swd_wait_until_halted(void)
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4)
|
||||
@ -740,6 +813,46 @@ uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t e
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t swd_flash_syscall_exec_ex(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4)
|
||||
{
|
||||
DEBUG_STATE state = {{0}, 0};
|
||||
// Call flash algorithm function on target and wait for result.
|
||||
state.r[0] = arg1; // R0: Argument 1
|
||||
state.r[1] = arg2; // R1: Argument 2
|
||||
state.r[2] = arg3; // R2: Argument 3
|
||||
state.r[3] = arg4; // R3: Argument 4
|
||||
state.r[9] = sysCallParam->static_base; // SB: Static Base
|
||||
state.r[13] = sysCallParam->stack_pointer; // SP: Stack Pointer
|
||||
state.r[14] = sysCallParam->breakpoint; // LR: Exit Point
|
||||
state.r[15] = entry; // PC: Entry Point
|
||||
state.xpsr = 0x01000000; // xPSR: T = 1, ISR = 0
|
||||
|
||||
if (!swd_write_debug_state(&state)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!swd_wait_until_halted()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!swd_read_core_register(0, &state.r[0])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//remove the C_MASKINTS
|
||||
if (!swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN | C_HALT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// // Flash functions return 0 if successful.
|
||||
// if (state.r[0] != 0) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// return 1;
|
||||
return state.r[0];
|
||||
}
|
||||
|
||||
// SWD Reset
|
||||
static uint8_t swd_reset(void)
|
||||
{
|
||||
@ -924,53 +1037,96 @@ uint8_t swd_set_target_state_hw(TARGET_RESET_STATE state)
|
||||
break;
|
||||
|
||||
case RESET_PROGRAM:
|
||||
if (!swd_init_debug()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reset_connect == CONNECT_UNDER_RESET) {
|
||||
// Assert reset
|
||||
swd_set_target_reset(1);
|
||||
osDelay(2);
|
||||
}
|
||||
{
|
||||
int k;
|
||||
int err = 0;
|
||||
|
||||
for (k = 0; k < 10; k++)
|
||||
{
|
||||
err = 0;
|
||||
if (!swd_init_debug()) {
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reset_connect == CONNECT_UNDER_RESET) {
|
||||
// Assert reset
|
||||
swd_set_target_reset(1);
|
||||
osDelay(20);
|
||||
}
|
||||
|
||||
// Enable debug
|
||||
while(swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN) == 0) {
|
||||
if( --ap_retries <=0 )
|
||||
return 0;
|
||||
// Target is in invalid state?
|
||||
swd_set_target_reset(1);
|
||||
osDelay(2);
|
||||
swd_set_target_reset(0);
|
||||
osDelay(2);
|
||||
}
|
||||
// Enable debug
|
||||
while(swd_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN) == 0) {
|
||||
if( --ap_retries <=0 )
|
||||
return 0;
|
||||
// Target is in invalid state?
|
||||
swd_set_target_reset(1);
|
||||
osDelay(20);
|
||||
swd_set_target_reset(0);
|
||||
osDelay(20);
|
||||
}
|
||||
|
||||
// Enable halt on reset
|
||||
if (!swd_write_word(DBG_EMCR, VC_CORERESET)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reset_connect == CONNECT_NORMAL) {
|
||||
// Assert reset
|
||||
swd_set_target_reset(1);
|
||||
osDelay(2);
|
||||
}
|
||||
|
||||
// Deassert reset
|
||||
swd_set_target_reset(0);
|
||||
osDelay(2);
|
||||
|
||||
do {
|
||||
if (!swd_read_word(DBG_HCSR, &val)) {
|
||||
// Enable halt on reset
|
||||
if (!swd_write_word(DBG_EMCR, VC_CORERESET)) {
|
||||
err = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reset_connect == CONNECT_NORMAL) {
|
||||
// Assert reset
|
||||
swd_set_target_reset(1);
|
||||
osDelay(10);
|
||||
}
|
||||
|
||||
// Deassert reset
|
||||
swd_set_target_reset(0);
|
||||
osDelay(20);
|
||||
|
||||
/* 2020-01-18 armfly 增加退出机制 */
|
||||
#if 1
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < 100000; i++)
|
||||
{
|
||||
if (!swd_read_word(DBG_HCSR, &val)) {
|
||||
err = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((val & S_HALT) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
do {
|
||||
if (!swd_read_word(DBG_HCSR, &val)) {
|
||||
return 0;
|
||||
}
|
||||
} while ((val & S_HALT) == 0);
|
||||
#endif
|
||||
|
||||
// Disable halt on reset
|
||||
if (!swd_write_word(DBG_EMCR, 0)) {
|
||||
err = 4;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} while ((val & S_HALT) == 0);
|
||||
|
||||
// Disable halt on reset
|
||||
if (!swd_write_word(DBG_EMCR, 0)) {
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NO_DEBUG:
|
||||
|
@ -22,8 +22,8 @@
|
||||
#ifndef SWDHOST_CM_H
|
||||
#define SWDHOST_CM_H
|
||||
|
||||
//#include "flash_blob.h"
|
||||
//#include "target_reset.h"
|
||||
#include "flash_blob.h"
|
||||
#include "target_reset.h"
|
||||
#ifdef TARGET_MCU_CORTEX_A
|
||||
#include "debug_ca.h"
|
||||
#else
|
||||
@ -56,6 +56,7 @@ uint8_t swd_write_memory(uint32_t address, uint8_t *data, uint32_t size);
|
||||
uint8_t swd_read_core_register(uint32_t n, uint32_t *val);
|
||||
uint8_t swd_write_core_register(uint32_t n, uint32_t val);
|
||||
uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
|
||||
uint32_t swd_flash_syscall_exec_ex(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
|
||||
uint8_t swd_set_target_state_hw(TARGET_RESET_STATE state);
|
||||
uint8_t swd_set_target_state_sw(TARGET_RESET_STATE state);
|
||||
uint8_t swd_transfer_retry(uint32_t req, uint32_t *data);
|
||||
|
@ -28,6 +28,9 @@
|
||||
#include "IO_Config.h"
|
||||
#include "bsp.h"
|
||||
|
||||
|
||||
#define SPI_MODE_ENABLE 0 /* 1 表示SPI模式, 0表示GPIO模式 */
|
||||
|
||||
//#include "uart.h"
|
||||
|
||||
//#include "debug_cm.h"
|
||||
@ -437,12 +440,17 @@ static __forceinline uint32_t PIN_SWDIO_IN(void)
|
||||
/** SWDIO I/O pin: Set Output (used in SWD mode only).
|
||||
\param bit Output value for the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
|
||||
static __forceinline void PIN_SWDIO_OUT(uint32_t bit)
|
||||
{
|
||||
if (bit & 1)
|
||||
{
|
||||
BSP_SET_GPIO_1(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
BSP_SET_GPIO_0(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
|
||||
@ -631,7 +639,9 @@ static __inline void DAP_SETUP(void)
|
||||
|
||||
EIO_D2_Config(ES_GPIO_OUT); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD> */
|
||||
|
||||
bsp_InitSPI2_Fast();
|
||||
#if SPI_MODE_ENABLE == 1
|
||||
bsp_InitSPI2_Fast();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Reset Target Device with custom specific I/O pin or command sequence.
|
||||
|
@ -63,13 +63,21 @@ COMPILER_ASSERT(DAPLINK_HIC_ID == DAPLINK_HIC_ID_STM32F103XB);
|
||||
#define SWCLK_TCK_PIN GPIO_PIN_3
|
||||
#define SWCLK_TCK_PIN_Bit 3
|
||||
|
||||
#define SWDIO_OUT_PIN_PORT GPIOI
|
||||
#define SWDIO_OUT_PIN GPIO_PIN_3
|
||||
#define SWDIO_OUT_PIN_Bit 3
|
||||
//#define SWDIO_OUT_PIN_PORT GPIOI
|
||||
//#define SWDIO_OUT_PIN GPIO_PIN_3
|
||||
//#define SWDIO_OUT_PIN_Bit 3
|
||||
|
||||
#define SWDIO_IN_PIN_PORT GPIOI
|
||||
#define SWDIO_IN_PIN GPIO_PIN_3
|
||||
#define SWDIO_IN_PIN_Bit 3
|
||||
//#define SWDIO_IN_PIN_PORT GPIOI
|
||||
//#define SWDIO_IN_PIN GPIO_PIN_3
|
||||
//#define SWDIO_IN_PIN_Bit 3
|
||||
|
||||
#define SWDIO_OUT_PIN_PORT GPIOD
|
||||
#define SWDIO_OUT_PIN GPIO_PIN_4
|
||||
#define SWDIO_OUT_PIN_Bit 4
|
||||
|
||||
#define SWDIO_IN_PIN_PORT GPIOD
|
||||
#define SWDIO_IN_PIN GPIO_PIN_4
|
||||
#define SWDIO_IN_PIN_Bit 4
|
||||
|
||||
//LEDs
|
||||
//USB status LED
|
||||
|
@ -403,7 +403,9 @@ unsigned char const g_Ascii24[] =
|
||||
0x00,0x00,0x7F,0xC0,0x60,0xC0,0x41,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,
|
||||
0x18,0x00,0x30,0x00,0x30,0x40,0x60,0xC0,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
|
||||
0x5F, 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,0xFF,0xE0,
|
||||
|
||||
|
||||
/* 最后一行必须用0xFF,0xFF结束,这是字库数组结束标志 */
|
||||
|
@ -41,11 +41,11 @@ static void lua_RegisterFunc(void);
|
||||
|
||||
static void LuaYeildHook(lua_State *_L, lua_Debug *ar);
|
||||
|
||||
/* lua源码调用该函数,会告警 */
|
||||
void exit(int status)
|
||||
{
|
||||
;
|
||||
}
|
||||
///* lua源码调用该函数,会告警 */
|
||||
//void exit(int status)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
int system(const char *cmd)
|
||||
{
|
||||
@ -126,6 +126,7 @@ void lua_DeInit(void)
|
||||
|
||||
// 每行执行的钩子函数,用于终止lua程序
|
||||
extern MEMO_T g_LuaMemo;
|
||||
extern void PG_PrintText(char *_str);
|
||||
void LuaYeildHook(lua_State *_L, lua_Debug *ar)
|
||||
{
|
||||
if (s_lua_quit == 1)
|
||||
@ -162,6 +163,29 @@ void LuaYeildHook(lua_State *_L, lua_Debug *ar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_MainStatus == MS_PROG_WORK)
|
||||
{
|
||||
uint8_t ucKeyCode;
|
||||
|
||||
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
|
||||
if (ucKeyCode != KEY_NONE)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)
|
||||
{
|
||||
case KEY_LONG_DOWN_C: /* C键长按 - 终止Lua */
|
||||
PG_PrintText("用户终止运行");
|
||||
|
||||
lua_yield(_L, 0);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 终止lua
|
||||
@ -178,7 +202,7 @@ void lua_DownLoadFile(char *_path)
|
||||
lua_Init();
|
||||
|
||||
// 读文件到内存
|
||||
s_lua_prog_len = ReadFileToMem(_path, s_lua_prog_buf, LUA_PROG_LEN_MAX);
|
||||
s_lua_prog_len = ReadFileToMem(_path, 0, s_lua_prog_buf, LUA_PROG_LEN_MAX);
|
||||
|
||||
if (s_lua_prog_len > 0)
|
||||
{
|
||||
@ -329,15 +353,38 @@ uint8_t lua_67H_Read(uint32_t _addr, uint8_t *_buf, uint32_t _len)
|
||||
*/
|
||||
static int beep(lua_State* L)
|
||||
{
|
||||
//检查栈中的参数是否合法,1表示Lua调用时的第一个参数(从左到右),依此类推。
|
||||
//如果Lua代码在调用时传递的参数不为number,该函数将报错并终止程序的执行。
|
||||
// double op1 = luaL_checknumber(L, 1);
|
||||
// double op2 = luaL_checknumber(L, 2);
|
||||
uint16_t usBeepTime;
|
||||
uint16_t usStopTime;
|
||||
uint16_t usCycle;
|
||||
|
||||
BEEP_KeyTone();
|
||||
|
||||
//将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
|
||||
//lua_pushnumber(L, op1 + op2);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数. */
|
||||
{
|
||||
usBeepTime = luaL_checknumber(L, 1);
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第2个参数. */
|
||||
{
|
||||
usStopTime = luaL_checknumber(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第3个参数. */
|
||||
{
|
||||
usCycle = luaL_checknumber(L, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEEP_Start(usBeepTime, usStopTime, usCycle); /* 鸣叫50ms,停10ms, 1次 */
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(5, 1, 1); /* 鸣叫50ms,停10ms, 1次 */
|
||||
}
|
||||
|
||||
//返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。
|
||||
return 0;
|
||||
@ -379,7 +426,7 @@ static int delayms(lua_State* L)
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: printhex
|
||||
* 功能说明: 打印hex格式. pr nthex(100, 2); p inthex("123");
|
||||
* 功能说明: 打印hex格式. printhex(100, 2); printhex("123");
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
@ -543,7 +590,7 @@ static int get_runtime(lua_State* L)
|
||||
static int check_runtime(lua_State* L)
|
||||
{
|
||||
int32_t lasttime;
|
||||
uint8_t re;
|
||||
int32_t re;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ static int lua_f_dir(lua_State* L)
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
data = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是stri 的长度 */
|
||||
data = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
|
||||
ViewDir((char *)data);
|
||||
|
@ -45,7 +45,7 @@ static int lua_I2C_SendBytes(lua_State* L)
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
data = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是stri 的长度 */
|
||||
data = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string 的长度 */
|
||||
}
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
|
@ -85,7 +85,7 @@ static int qspi_write(lua_State* L)
|
||||
|
||||
if (lua_type(L, 2) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
data = luaL_checklstring(L, 2, &len); /* 1是参数的位置, len是stri 的长度 */
|
||||
data = luaL_checklstring(L, 2, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
|
||||
if (len > QSPI_PAGE_SIZE)
|
||||
@ -120,7 +120,7 @@ static int qspi_read(lua_State* L)
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
{
|
||||
addr = luaL_checknumber(L, 1); /* 1是参数的位置, len是stri 的长度 */
|
||||
addr = luaL_checknumber(L, 1); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) /* 判断第2个参数 */
|
||||
|
@ -3,11 +3,15 @@
|
||||
#include "time.h"
|
||||
#include "lua_if.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#include "elf_file.h"
|
||||
#include "file_lib.h"
|
||||
#include "prog_if.h"
|
||||
#include "target_reset.h"
|
||||
#include "target_config.h"
|
||||
#include "swd_host.h"
|
||||
#include "Systick_Handler.h"
|
||||
#include "main.h"
|
||||
#include "target_family.h"
|
||||
|
||||
/* 为了避免和DAP驱动中的函数混淆,本模块函数名前缀用 h7swd */
|
||||
|
||||
@ -16,6 +20,18 @@ static int h7swd_ReadID(lua_State* L);
|
||||
static int h7swd_WriteMemory(lua_State* L);
|
||||
static int h7swd_ReadMemory(lua_State* L);
|
||||
|
||||
static int h7_LoadAlgoFile(lua_State* L);
|
||||
static int h7_ProgFile(lua_State* L);
|
||||
static int h7_ProgBuf(lua_State* L);
|
||||
static int h7_ProgBuf_OB(lua_State* L);
|
||||
static int h7_reset(lua_State* L);
|
||||
static int h7_DetectIC(lua_State* L);
|
||||
static int h7_PrintText(lua_State* L);
|
||||
static int h7_EraseChip(lua_State* L);
|
||||
|
||||
static int h7_Read_ProductSN(lua_State* L);
|
||||
static int h7_Write_ProductSN(lua_State* L);
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: lua_swd_RegisterFun
|
||||
@ -24,6 +40,7 @@ static int h7swd_ReadMemory(lua_State* L);
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
extern void PG_PrintText(char *_str);
|
||||
void lua_swd_RegisterFun(void)
|
||||
{
|
||||
//将指定的函数注册为Lua的全局函数变量,其中第一个字符串参数为Lua代码
|
||||
@ -32,13 +49,25 @@ void lua_swd_RegisterFun(void)
|
||||
lua_register(g_Lua, "swd_getid", h7swd_ReadID);
|
||||
lua_register(g_Lua, "swd_write", h7swd_WriteMemory);
|
||||
lua_register(g_Lua, "swd_read", h7swd_ReadMemory);
|
||||
|
||||
lua_register(g_Lua, "pg_load_algo_file", h7_LoadAlgoFile);
|
||||
lua_register(g_Lua, "pg_prog_file", h7_ProgFile);
|
||||
lua_register(g_Lua, "pg_prog_buf", h7_ProgBuf);
|
||||
lua_register(g_Lua, "pg_prog_buf_ob", h7_ProgBuf_OB);
|
||||
lua_register(g_Lua, "pg_reset", h7_reset);
|
||||
lua_register(g_Lua, "pg_detect_ic", h7_DetectIC);
|
||||
lua_register(g_Lua, "pg_erase_chip", h7_EraseChip);
|
||||
|
||||
lua_register(g_Lua, "pg_print_text", h7_PrintText);
|
||||
lua_register(g_Lua, "pg_read_sn", h7_Read_ProductSN);
|
||||
lua_register(g_Lua, "pg_write_sn", h7_Write_ProductSN);
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7swd_Init
|
||||
* 功能说明: 读芯片ID
|
||||
* 形 参: vcc : CPU供电电压
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
@ -54,9 +83,9 @@ static int h7swd_Init(lua_State* L)
|
||||
}
|
||||
|
||||
bsp_SetTVCC(vcc * 1000); /* 设置接口电平3.3V */
|
||||
bsp_DelayUS(100 * 100); /* 延迟100ms */
|
||||
bsp_DelayUS(100 * 100); /* 延迟100ms */
|
||||
|
||||
swd_init_debug(); /* 进入swd debug状态 */
|
||||
swd_init_debug(); /* 进入swd debug状态 */
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -113,7 +142,7 @@ static int h7swd_WriteMemory(lua_State* L)
|
||||
|
||||
if (lua_type(L, 2) == LUA_TSTRING) /* 判断第2个参数 */
|
||||
{
|
||||
data = luaL_checklstring(L, 2, &len); /* 1是参数的位置, len是stri 的长度 */
|
||||
data = luaL_checklstring(L, 2, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
|
||||
if (len > 128 * 1024)
|
||||
@ -150,7 +179,7 @@ static int h7swd_ReadMemory(lua_State* L)
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
{
|
||||
addr = luaL_checknumber(L, 1); /* 1是参数的位置, len是stri 的长度 */
|
||||
addr = luaL_checknumber(L, 1); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -181,7 +210,418 @@ static int h7swd_ReadMemory(lua_State* L)
|
||||
}
|
||||
|
||||
lua_pushlstring(L, (char *)s_lua_read_buf, num);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_LoadAlgoFile
|
||||
* 功能说明: 装载算法文件
|
||||
* 形 参: file_path 算法文件路径,是相对路径
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_LoadAlgoFile(lua_State* L)
|
||||
{
|
||||
// pg_load_algo_file(AlgoFile, AlgoRamAddr, AlgoRamSize)
|
||||
const char *data;
|
||||
size_t len = 0;
|
||||
|
||||
g_AlgoRam.Valid = 0;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
data = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) /* 判断第2个参数 */
|
||||
{
|
||||
g_AlgoRam.Addr = luaL_checknumber(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 3) == LUA_TNUMBER) /* 判断第3个参数 */
|
||||
{
|
||||
g_AlgoRam.Size = luaL_checknumber(L, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_AlgoRam.Valid = 1;
|
||||
|
||||
/* lua程序提供的路径是相对路径 */
|
||||
{
|
||||
char FullPath[128];
|
||||
|
||||
if (strlen(PROG_FLM_DIR) + strlen(data) >= sizeof(FullPath))
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 文件名过长 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf(FullPath, "%s/%s", PROG_FLM_DIR, data);
|
||||
if (ELF_ParseFile((char *)FullPath) != 0)
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnumber(L, 1); /*OK */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_ProgFile
|
||||
* 功能说明: 开始编程,从文件读取数据
|
||||
* 形 参: file_path 数据文件名称, 目标flash地址
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_ProgFile(lua_State* L)
|
||||
{
|
||||
const char *file_name;
|
||||
size_t len = 0;
|
||||
uint32_t FlashAddr;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
file_name = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) /* 判断第2个参数 */
|
||||
{
|
||||
FlashAddr = luaL_checknumber(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (PG_ProgFile((char *)file_name, FlashAddr) == 0)
|
||||
{
|
||||
lua_pushnumber(L, 1); /*OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_reset
|
||||
* 功能说明: 执行硬件复位
|
||||
* 形 参: 无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_reset(lua_State* L)
|
||||
{
|
||||
/* 软件复位目标板 M3 - M7 好像都一样的操作 (该功能需要测试) */
|
||||
{
|
||||
uint32_t reg_addr;
|
||||
uint32_t reg_value;
|
||||
|
||||
reg_addr = (uint32_t )&SCB->AIRCR;
|
||||
reg_value = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
|
||||
swd_write_memory(reg_addr, (uint8_t *)®_value, 4);
|
||||
}
|
||||
|
||||
/* 硬件复位 */
|
||||
{
|
||||
swd_set_target_reset(1);
|
||||
osDelay(20);
|
||||
swd_set_target_reset(0);
|
||||
osDelay(20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_DetectIC
|
||||
* 功能说明: 检测CPU ID
|
||||
* 形 参: 无
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_DetectIC(lua_State* L)
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t id;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
sysTickInit(); /* 这是DAP驱动中的初始化函数,全局变量初始化 */
|
||||
|
||||
bsp_DelayUS(100 * 100); /* 延迟100ms */
|
||||
|
||||
swd_init_debug(); /* 进入swd debug状态 */
|
||||
|
||||
if (swd_read_idcode(&id) == 0)
|
||||
{
|
||||
id = 0; /* 出错继续检测 */
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnumber(L, id); /* 成功,返回ID */
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
PG_PrintText("未检测到芯片");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_PrintText
|
||||
* 功能说明: 在LCD显示一串文本
|
||||
* 形 参: 无
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_PrintText(lua_State* L)
|
||||
{
|
||||
const char *str;
|
||||
size_t len = 0;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
str = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
|
||||
if (g_MainStatus == MS_PROG_WORK)
|
||||
{
|
||||
printf(str);
|
||||
|
||||
if (g_MainStatus == MS_PROG_WORK)
|
||||
{
|
||||
DispProgProgress((char *)str, -1); /* -1表示不刷新进度 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_ProgBuf
|
||||
* 功能说明: 开始编程,从新参读入数据。
|
||||
* 形 参: Flash地址
|
||||
* 数据
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_ProgBuf(lua_State* L)
|
||||
{
|
||||
const char *str;
|
||||
uint8_t buf[2048];
|
||||
size_t len = 0;
|
||||
uint32_t FlashAddr;
|
||||
uint8_t mode;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
str = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) /* 判断第2个参数 */
|
||||
{
|
||||
FlashAddr = luaL_checknumber(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 3) == LUA_TNUMBER) /* 判断第3个参数 */
|
||||
{
|
||||
mode = luaL_checknumber(L, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 将字符换转换为2进制数组
|
||||
"FF 00 12 34" -> 0xFF,0x00,0x12,0x34
|
||||
*/
|
||||
len = AsciiToHex((char *)str, buf, sizeof(buf));
|
||||
|
||||
if (PG_ProgBuf(FlashAddr, buf, len, mode) == 0)
|
||||
{
|
||||
lua_pushnumber(L, 1); /*OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_ProgBuf_OB
|
||||
* 功能说明: 开始编程,从新参读入数据。 用于option bytes
|
||||
* 形 参: Flash地址
|
||||
* 数据
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_ProgBuf_OB(lua_State* L)
|
||||
{
|
||||
const char *str;
|
||||
uint8_t buf[2048];
|
||||
size_t len = 0;
|
||||
uint32_t FlashAddr;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TSTRING) /* 判断第1个参数 */
|
||||
{
|
||||
str = luaL_checklstring(L, 1, &len); /* 1是参数的位置, len是string的长度 */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) /* 判断第2个参数 */
|
||||
{
|
||||
FlashAddr = luaL_checknumber(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 将字符换转换为2进制数组
|
||||
"FF 00 12 34" -> 0xFF,0x00,0x12,0x34
|
||||
*/
|
||||
len = AsciiToHex((char *)str, buf, sizeof(buf));
|
||||
|
||||
if (PG_ProgBuf_OB(FlashAddr, buf, len) == 0)
|
||||
{
|
||||
lua_pushnumber(L, 1); /*OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_EraseChip
|
||||
* 功能说明: 擦除全片,用于OPTION BYTES编程,去除读保护。
|
||||
* 形 参: Flash地址
|
||||
* 数据
|
||||
* 返 回 值: 0 失败 1 成功
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_EraseChip(lua_State* L)
|
||||
{
|
||||
uint32_t FlashAddr;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
{
|
||||
FlashAddr = luaL_checknumber(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (PG_EraseChip(FlashAddr) == 0)
|
||||
{
|
||||
lua_pushnumber(L, 1); /* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_Read_ProductSN
|
||||
* 功能说明: 读产品序号
|
||||
* 形 参: 无
|
||||
* 返 回 值: 序号(整数)
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_Read_ProductSN(lua_State* L)
|
||||
{
|
||||
lua_pushnumber(L, g_tProgIni.ProductSN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: h7_Write_ProductSN
|
||||
* 功能说明: 写产品序号
|
||||
* 形 参: 无
|
||||
* 返 回 值: 序号(整数)
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static int h7_Write_ProductSN(lua_State* L)
|
||||
{
|
||||
uint32_t sn;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
|
||||
{
|
||||
sn = luaL_checknumber(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnumber(L, 0); /* 出错 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_tProgIni.ProductSN = sn;
|
||||
lua_pushnumber(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
|
@ -369,7 +369,6 @@ static int os_setlocale (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int os_exit (lua_State *L) {
|
||||
int status;
|
||||
if (lua_isboolean(L, 1))
|
||||
@ -378,7 +377,8 @@ static int os_exit (lua_State *L) {
|
||||
status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
|
||||
if (lua_toboolean(L, 2))
|
||||
lua_close(L);
|
||||
if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
|
||||
// if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
|
||||
status = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
89
User/programmer/FlashOS.h
Normal file
89
User/programmer/FlashOS.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2014 ARM Ltd.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software. Permission is granted to anyone to use this
|
||||
* software for any purpose, including commercial applications, and to alter
|
||||
* it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
*
|
||||
* $Date: 14. Jan 2014
|
||||
* $Revision: V1.00
|
||||
*
|
||||
* Project: FlashOS Headerfile for Flash drivers
|
||||
* --------------------------------------------------------------------------- */
|
||||
|
||||
/* History:
|
||||
* Version 1.00
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#ifndef __FLASHOS_H_
|
||||
#define __FLASHOS_H_
|
||||
|
||||
#define VERS 1 // Interface Version 1.01
|
||||
|
||||
#define UNKNOWN 0 // Unknown
|
||||
#define ONCHIP 1 // On-chip Flash Memory
|
||||
#define EXT8BIT 2 // External Flash Device on 8-bit Bus
|
||||
#define EXT16BIT 3 // External Flash Device on 16-bit Bus
|
||||
#define EXT32BIT 4 // External Flash Device on 32-bit Bus
|
||||
#define EXTSPI 5 // External Flash Device on SPI
|
||||
|
||||
#define SECTOR_NUM 512 // Max Number of Sector Items
|
||||
#define PAGE_MAX 65536 // Max Page Size for Programming
|
||||
|
||||
struct FlashSectors {
|
||||
unsigned long szSector; // Sector Size in Bytes
|
||||
unsigned long AddrSector; // Address of Sector
|
||||
};
|
||||
|
||||
#define SECTOR_END 0xFFFFFFFF, 0xFFFFFFFF
|
||||
|
||||
typedef struct {
|
||||
unsigned short Vers; // Version Number and Architecture
|
||||
char DevName[128]; // Device Name and Description
|
||||
unsigned short DevType; // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
|
||||
unsigned long DevAdr; // Default Device Start Address
|
||||
unsigned long szDev; // Total Size of Device
|
||||
unsigned long szPage; // Programming Page Size
|
||||
unsigned long Res; // Reserved for future Extension
|
||||
unsigned char valEmpty; // Content of Erased Memory
|
||||
|
||||
unsigned long toProg; // Time Out of Program Page Function
|
||||
unsigned long toErase; // Time Out of Erase Sector Function
|
||||
|
||||
struct FlashSectors sectors[SECTOR_NUM];
|
||||
}FlashDevice_T;
|
||||
|
||||
#define FLASH_DRV_VERS (0x0100+VERS) // Driver Version, do not modify!
|
||||
|
||||
// Flash Programming Functions (Called by FlashOS)
|
||||
extern int Init (unsigned long adr, // Initialize Flash
|
||||
unsigned long clk,
|
||||
unsigned long fnc);
|
||||
extern int UnInit (unsigned long fnc); // De-initialize Flash
|
||||
extern int BlankCheck (unsigned long adr, // Blank Check
|
||||
unsigned long sz,
|
||||
unsigned char pat);
|
||||
extern int EraseChip (void); // Erase complete Device
|
||||
extern int EraseSector (unsigned long adr); // Erase Sector Function
|
||||
extern int ProgramPage (unsigned long adr, // Program Page Function
|
||||
unsigned long sz,
|
||||
unsigned char *buf);
|
||||
extern unsigned long Verify (unsigned long adr, // Verify Function
|
||||
unsigned long sz,
|
||||
unsigned char *buf);
|
||||
|
||||
#endif
|
169
User/programmer/SWD_flash.c
Normal file
169
User/programmer/SWD_flash.c
Normal file
@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @file SWD_flash.c
|
||||
* @brief Program target flash through SWD
|
||||
*/
|
||||
#include "swd_host.h"
|
||||
#include "SWD_flash.h"
|
||||
#include "prog_if.h"
|
||||
#include "elf_file.h"
|
||||
|
||||
extern const program_target_t flash_algo;
|
||||
|
||||
|
||||
error_t target_flash_init(uint32_t flash_start)
|
||||
{
|
||||
// DAP_Data.clock_delay = 5;
|
||||
// DAP_Data.fast_clock = 0;
|
||||
|
||||
if (0 == swd_set_target_state_hw(RESET_PROGRAM)) {
|
||||
return ERROR_RESET;
|
||||
}
|
||||
|
||||
// DAP_Data.clock_delay = 1;
|
||||
// DAP_Data.fast_clock = 1;
|
||||
|
||||
// Download flash programming algorithm to target and initialise.
|
||||
if (0 == swd_write_memory(flash_algo.algo_start, (uint8_t *)flash_algo.algo_blob, flash_algo.algo_size)) {
|
||||
return ERROR_ALGO_DL;
|
||||
}
|
||||
|
||||
g_tProg.FLMFuncTimeout = 500; /* 超时 */
|
||||
|
||||
if (0 == swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.init, flash_start, 0, 0, 0)) {
|
||||
return ERROR_INIT;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_uninit(void)
|
||||
{
|
||||
g_tProg.FLMFuncTimeout = 200; /* 函数执行超时 */
|
||||
|
||||
swd_set_target_state_hw(RESET_RUN);
|
||||
|
||||
swd_off();
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size)
|
||||
{
|
||||
/*
|
||||
FLM中的超时3秒, 如果是解除读保护,这个时间就不够,因此不要在此赋值
|
||||
g_tProg.FLMFuncTimeout = g_tFLM.Device.toProg; // page编程超时
|
||||
*/
|
||||
g_tProg.FLMFuncTimeout = 60 * 1000;
|
||||
while (size > 0) {
|
||||
uint32_t write_size = size > flash_algo.program_buffer_size ? flash_algo.program_buffer_size : size;
|
||||
|
||||
// Write page to buffer
|
||||
if (!swd_write_memory(flash_algo.program_buffer, (uint8_t *)buf, write_size)) {
|
||||
return ERROR_ALGO_DATA_SEQ;
|
||||
}
|
||||
|
||||
|
||||
// Run flash programming
|
||||
if (!swd_flash_syscall_exec(&flash_algo.sys_call_s,
|
||||
flash_algo.program_page,
|
||||
addr,
|
||||
flash_algo.program_buffer_size,
|
||||
flash_algo.program_buffer,
|
||||
0)) {
|
||||
return ERROR_WRITE;
|
||||
}
|
||||
|
||||
addr += write_size;
|
||||
buf += write_size;
|
||||
size -= write_size;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* 校验函数 */
|
||||
error_t target_flash_verify_page(uint32_t addr, const uint8_t *buf, uint32_t size)
|
||||
{
|
||||
g_tProg.FLMFuncTimeout = 3000;
|
||||
while (size > 0)
|
||||
{
|
||||
uint32_t write_size = size > flash_algo.program_buffer_size ? flash_algo.program_buffer_size : size;
|
||||
|
||||
// Write page to buffer
|
||||
if (!swd_write_memory(flash_algo.program_buffer, (uint8_t *)buf, write_size)) {
|
||||
return ERROR_ALGO_DATA_SEQ;
|
||||
}
|
||||
|
||||
// Run verify programming
|
||||
if (swd_flash_syscall_exec_ex(&flash_algo.sys_call_s,
|
||||
flash_algo.verify,
|
||||
addr,
|
||||
flash_algo.program_buffer_size,
|
||||
flash_algo.program_buffer,
|
||||
0) != addr + size)
|
||||
{
|
||||
return ERROR_WRITE;
|
||||
}
|
||||
|
||||
addr += write_size;
|
||||
buf += write_size;
|
||||
size -= write_size;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* 查空函数, 1表示不空需要擦除 */
|
||||
uint8_t target_flash_check_blank(uint32_t addr, uint32_t size)
|
||||
{
|
||||
// Run verify programming
|
||||
if (1 == swd_flash_syscall_exec(&flash_algo.sys_call_s,
|
||||
flash_algo.check_blank,
|
||||
addr,
|
||||
size,
|
||||
0xFF,
|
||||
0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 计算flash crc32 */
|
||||
uint32_t target_flash_cacul_crc32(uint32_t addr, uint32_t size, uint32_t ini_value)
|
||||
{
|
||||
uint32_t crc;
|
||||
|
||||
// Run verify programming
|
||||
crc = swd_flash_syscall_exec_ex(&flash_algo.sys_call_s,
|
||||
flash_algo.cacul_crc32,
|
||||
addr,
|
||||
size,
|
||||
ini_value,
|
||||
0);
|
||||
return crc;
|
||||
}
|
||||
|
||||
error_t target_flash_erase_sector(uint32_t addr)
|
||||
{
|
||||
g_tProg.FLMFuncTimeout = 60 * 1000;
|
||||
|
||||
if (0 == swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.erase_sector, addr, 0, 0, 0)) {
|
||||
return ERROR_ERASE_SECTOR;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t target_flash_erase_chip(void)
|
||||
{
|
||||
error_t status = ERROR_SUCCESS;
|
||||
|
||||
g_tProg.FLMFuncTimeout = 60 * 1000;
|
||||
|
||||
if (0 == swd_flash_syscall_exec(&flash_algo.sys_call_s, flash_algo.erase_chip, 0, 0, 0, 0))
|
||||
{
|
||||
return ERROR_ERASE_ALL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
17
User/programmer/SWD_flash.h
Normal file
17
User/programmer/SWD_flash.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __SWD_FLASH_H__
|
||||
#define __SWD_FLASH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
error_t target_flash_init(uint32_t flash_start);
|
||||
error_t target_flash_uninit(void);
|
||||
error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size);
|
||||
error_t target_flash_verify_page(uint32_t addr, const uint8_t *buf, uint32_t size);
|
||||
error_t target_flash_erase_sector(uint32_t addr);
|
||||
error_t target_flash_erase_chip(void);
|
||||
uint8_t target_flash_check_blank(uint32_t addr, uint32_t size);
|
||||
uint32_t target_flash_cacul_crc32(uint32_t addr, uint32_t size, uint32_t ini_value);
|
||||
|
||||
#endif // __SWD_FLASH_H__
|
644
User/programmer/elf.h
Normal file
644
User/programmer/elf.h
Normal file
@ -0,0 +1,644 @@
|
||||
/* $OpenBSD: exec_elf.h,v 1.41 2006/01/06 18:53:05 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above cElf32_Ehdropyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the ELF ABI header file
|
||||
* formerly known as "elf_abi.h".
|
||||
*/
|
||||
|
||||
#ifndef _SYS_EXEC_ELF_H_
|
||||
#define _SYS_EXEC_ELF_H_
|
||||
|
||||
#define ELFSIZE 32
|
||||
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
typedef int __int32_t;
|
||||
typedef short __int16_t;
|
||||
typedef unsigned short __uint16_t;
|
||||
typedef uint64_t __uint64_t;
|
||||
typedef int64_t __int64_t;
|
||||
|
||||
|
||||
typedef __uint8_t Elf_Byte;
|
||||
|
||||
typedef __uint32_t Elf32_Addr; /* Unsigned program address */
|
||||
typedef __uint32_t Elf32_Off; /* Unsigned file offset */
|
||||
typedef __int32_t Elf32_Sword; /* Signed large integer */
|
||||
typedef __uint32_t Elf32_Word; /* Unsigned large integer */
|
||||
typedef __uint16_t Elf32_Half; /* Unsigned medium integer */
|
||||
|
||||
typedef __uint64_t Elf64_Addr;
|
||||
typedef __uint64_t Elf64_Off;
|
||||
typedef __int32_t Elf64_Shalf;
|
||||
|
||||
#ifdef __alpha__
|
||||
typedef __int64_t Elf64_Sword;
|
||||
typedef __uint64_t Elf64_Word;
|
||||
#else
|
||||
typedef __int32_t Elf64_Sword;
|
||||
typedef __uint32_t Elf64_Word;
|
||||
#endif
|
||||
|
||||
typedef __int64_t Elf64_Sxword;
|
||||
typedef __uint64_t Elf64_Xword;
|
||||
|
||||
typedef __uint32_t Elf64_Half;
|
||||
typedef __uint16_t Elf64_Quarter;
|
||||
|
||||
/*
|
||||
* e_ident[] identification indexes
|
||||
* See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html
|
||||
*/
|
||||
#define EI_MAG0 0 /* file ID */
|
||||
#define EI_MAG1 1 /* file ID */
|
||||
#define EI_MAG2 2 /* file ID */
|
||||
#define EI_MAG3 3 /* file ID */
|
||||
#define EI_CLASS 4 /* file class */
|
||||
#define EI_DATA 5 /* data encoding */
|
||||
#define EI_VERSION 6 /* ELF header version */
|
||||
#define EI_OSABI 7 /* OS/ABI ID */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define EI_PAD 9 /* start of pad bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
/* e_ident[] magic number */
|
||||
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
|
||||
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
|
||||
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
|
||||
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
|
||||
#define ELFMAG "\177ELF" /* magic */
|
||||
#define SELFMAG 4 /* size of magic */
|
||||
|
||||
/* e_ident[] file class */
|
||||
#define ELFCLASSNONE 0 /* invalid */
|
||||
#define ELFCLASS32 1 /* 32-bit objs */
|
||||
#define ELFCLASS64 2 /* 64-bit objs */
|
||||
#define ELFCLASSNUM 3 /* number of classes */
|
||||
|
||||
/* e_ident[] data encoding */
|
||||
#define ELFDATANONE 0 /* invalid */
|
||||
#define ELFDATA2LSB 1 /* Little-Endian */
|
||||
#define ELFDATA2MSB 2 /* Big-Endian */
|
||||
#define ELFDATANUM 3 /* number of data encode defines */
|
||||
|
||||
/* e_ident[] Operating System/ABI */
|
||||
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
|
||||
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* GNU/Linux */
|
||||
#define ELFOSABI_HURD 4 /* GNU/Hurd */
|
||||
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
|
||||
#define ELFOSABI_SOLARIS 6 /* Solaris */
|
||||
#define ELFOSABI_MONTEREY 7 /* Monterey */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
/* e_ident */
|
||||
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
|
||||
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
|
||||
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
|
||||
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
|
||||
|
||||
/* ELF Header */
|
||||
typedef struct elfhdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
|
||||
Elf32_Half e_type; /* object file type */
|
||||
Elf32_Half e_machine; /* machine */
|
||||
Elf32_Word e_version; /* object file version */
|
||||
Elf32_Addr e_entry; /* virtual entry point */
|
||||
Elf32_Off e_phoff; /* program header table offset */
|
||||
Elf32_Off e_shoff; /* section header table offset */
|
||||
Elf32_Word e_flags; /* processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size */
|
||||
Elf32_Half e_phentsize; /* program header entry size */
|
||||
Elf32_Half e_phnum; /* number of program header entries */
|
||||
Elf32_Half e_shentsize; /* section header entry size */
|
||||
Elf32_Half e_shnum; /* number of section header entries */
|
||||
Elf32_Half e_shstrndx; /* section header table's "section
|
||||
header string table" entry offset */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT]; /* Id bytes */
|
||||
Elf64_Quarter e_type; /* file type */
|
||||
Elf64_Quarter e_machine; /* machine type */
|
||||
Elf64_Half e_version; /* version number */
|
||||
Elf64_Addr e_entry; /* entry point */
|
||||
Elf64_Off e_phoff; /* Program hdr offset */
|
||||
Elf64_Off e_shoff; /* Section hdr offset */
|
||||
Elf64_Half e_flags; /* Processor flags */
|
||||
Elf64_Quarter e_ehsize; /* sizeof ehdr */
|
||||
Elf64_Quarter e_phentsize; /* Program header entry size */
|
||||
Elf64_Quarter e_phnum; /* Number of program headers */
|
||||
Elf64_Quarter e_shentsize; /* Section header entry size */
|
||||
Elf64_Quarter e_shnum; /* Number of section headers */
|
||||
Elf64_Quarter e_shstrndx; /* String table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* e_type */
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* relocatable file */
|
||||
#define ET_EXEC 2 /* executable file */
|
||||
#define ET_DYN 3 /* shared object file */
|
||||
#define ET_CORE 4 /* core file */
|
||||
#define ET_NUM 5 /* number of types */
|
||||
#define ET_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define ET_HIPROC 0xffff /* specific e_type */
|
||||
|
||||
/* e_machine */
|
||||
#define EM_NONE 0 /* No Machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 80486 - unused? */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
|
||||
/*
|
||||
* Don't know if EM_MIPS_RS4_BE,
|
||||
* EM_SPARC64, EM_PARISC,
|
||||
* or EM_PPC are ABI compliant
|
||||
*/
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_ARM 40 /* Advanced RISC Machines ARM */
|
||||
#define EM_ALPHA 41 /* DEC ALPHA */
|
||||
#define EM_SPARCV9 43 /* SPARC version 9 */
|
||||
#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */
|
||||
#define EM_AMD64 62 /* AMD64 architecture */
|
||||
#define EM_VAX 75 /* DEC VAX */
|
||||
#define EM_NUM 15 /* number of machine types */
|
||||
|
||||
/* Version */
|
||||
#define EV_NONE 0 /* Invalid */
|
||||
#define EV_CURRENT 1 /* Current */
|
||||
#define EV_NUM 2 /* number of versions */
|
||||
|
||||
/* Section Header */
|
||||
typedef struct {
|
||||
Elf32_Word sh_name; /* name - index into section header
|
||||
string table section */
|
||||
Elf32_Word sh_type; /* type */
|
||||
Elf32_Word sh_flags; /* flags */
|
||||
Elf32_Addr sh_addr; /* address */
|
||||
Elf32_Off sh_offset; /* file offset */
|
||||
Elf32_Word sh_size; /* section size */
|
||||
Elf32_Word sh_link; /* section header table index link */
|
||||
Elf32_Word sh_info; /* extra information */
|
||||
Elf32_Word sh_addralign; /* address alignment */
|
||||
Elf32_Word sh_entsize; /* section entry size */
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Half sh_name; /* section name */
|
||||
Elf64_Half sh_type; /* section type */
|
||||
Elf64_Xword sh_flags; /* section flags */
|
||||
Elf64_Addr sh_addr; /* virtual address */
|
||||
Elf64_Off sh_offset; /* file offset */
|
||||
Elf64_Xword sh_size; /* section size */
|
||||
Elf64_Half sh_link; /* link to another */
|
||||
Elf64_Half sh_info; /* misc info */
|
||||
Elf64_Xword sh_addralign; /* memory alignment */
|
||||
Elf64_Xword sh_entsize; /* table entry size */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* Special Section Indexes */
|
||||
#define SHN_UNDEF 0 /* undefined */
|
||||
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
|
||||
#define SHN_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define SHN_HIPROC 0xff1f /* specific section indexes */
|
||||
#define SHN_ABS 0xfff1 /* absolute value */
|
||||
#define SHN_COMMON 0xfff2 /* common symbol */
|
||||
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0 /* inactive */
|
||||
#define SHT_PROGBITS 1 /* program defined information */
|
||||
#define SHT_SYMTAB 2 /* symbol table section */
|
||||
#define SHT_STRTAB 3 /* string table section */
|
||||
#define SHT_RELA 4 /* relocation section with addends*/
|
||||
#define SHT_HASH 5 /* symbol hash table section */
|
||||
#define SHT_DYNAMIC 6 /* dynamic section */
|
||||
#define SHT_NOTE 7 /* note section */
|
||||
#define SHT_NOBITS 8 /* no space section */
|
||||
#define SHT_REL 9 /* relation section without addends */
|
||||
#define SHT_SHLIB 10 /* reserved - purpose unknown */
|
||||
#define SHT_DYNSYM 11 /* dynamic symbol table section */
|
||||
#define SHT_NUM 12 /* number of section types */
|
||||
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define SHT_HIPROC 0x7fffffff /* specific section header types */
|
||||
#define SHT_LOUSER 0x80000000 /* reserved range for application */
|
||||
#define SHT_HIUSER 0xffffffff /* specific indexes */
|
||||
|
||||
/* Section names */
|
||||
#define ELF_BSS ".bss" /* uninitialized data */
|
||||
#define ELF_DATA ".data" /* initialized data */
|
||||
#define ELF_DEBUG ".debug" /* debug */
|
||||
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
|
||||
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
|
||||
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
|
||||
#define ELF_FINI ".fini" /* termination code */
|
||||
#define ELF_GOT ".got" /* global offset table */
|
||||
#define ELF_HASH ".hash" /* symbol hash table */
|
||||
#define ELF_INIT ".init" /* initialization code */
|
||||
#define ELF_REL_DATA ".rel.data" /* relocation data */
|
||||
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
|
||||
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
|
||||
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
|
||||
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
|
||||
#define ELF_REL_TEXT ".rel.text" /* relocation code */
|
||||
#define ELF_RODATA ".rodata" /* read-only data */
|
||||
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
|
||||
#define ELF_STRTAB ".strtab" /* string table */
|
||||
#define ELF_SYMTAB ".symtab" /* symbol table */
|
||||
#define ELF_TEXT ".text" /* code */
|
||||
|
||||
|
||||
/* Section Attribute Flags - sh_flags */
|
||||
#define SHF_WRITE 0x1 /* Writable */
|
||||
#define SHF_ALLOC 0x2 /* occupies memory */
|
||||
#define SHF_EXECINSTR 0x4 /* executable */
|
||||
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific section attributes */
|
||||
|
||||
/* Symbol Table Entry */
|
||||
typedef struct elf32_sym {
|
||||
Elf32_Word st_name; /* name - index into string table */
|
||||
Elf32_Addr st_value; /* symbol value */
|
||||
Elf32_Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* type and binding */
|
||||
unsigned char st_other; /* 0 - no defined meaning */
|
||||
Elf32_Half st_shndx; /* section header index */
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Half st_name; /* Symbol name index in str table */
|
||||
Elf_Byte st_info; /* type / binding attrs */
|
||||
Elf_Byte st_other; /* unused */
|
||||
Elf64_Quarter st_shndx; /* section index of symbol */
|
||||
Elf64_Xword st_value; /* value of symbol */
|
||||
Elf64_Xword st_size; /* size of symbol */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* Symbol table index */
|
||||
#define STN_UNDEF 0 /* undefined */
|
||||
|
||||
/* Extract symbol info - st_info */
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||
|
||||
#define ELF64_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||
|
||||
/* Symbol Binding - ELF32_ST_BIND - st_info */
|
||||
#define STB_LOCAL 0 /* Local symbol */
|
||||
#define STB_GLOBAL 1 /* Global symbol */
|
||||
#define STB_WEAK 2 /* like global - lower precedence */
|
||||
#define STB_NUM 3 /* number of symbol bindings */
|
||||
#define STB_LOPROC 13 /* reserved range for processor */
|
||||
#define STB_HIPROC 15 /* specific symbol bindings */
|
||||
|
||||
/* Symbol type - ELF32_ST_TYPE - st_info */
|
||||
#define STT_NOTYPE 0 /* not specified */
|
||||
#define STT_OBJECT 1 /* data object */
|
||||
#define STT_FUNC 2 /* function */
|
||||
#define STT_SECTION 3 /* section */
|
||||
#define STT_FILE 4 /* file */
|
||||
#define STT_NUM 5 /* number of symbol types */
|
||||
#define STT_LOPROC 13 /* reserved range for processor */
|
||||
#define STT_HIPROC 15 /* specific symbol types */
|
||||
|
||||
/* Relocation entry with implicit addend */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* Relocation entry with explicit addend */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
/* Extract relocation info - r_info */
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char) (i))
|
||||
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
|
||||
|
||||
typedef struct {
|
||||
Elf64_Xword r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Xword r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
Elf64_Sxword r_addend; /* adjustment value */
|
||||
} Elf64_Rela;
|
||||
|
||||
#define ELF64_R_SYM(info) ((info) >> 32)
|
||||
#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s,t) (((s) << 32) + (__uint32_t)(t))
|
||||
|
||||
/* Program Header */
|
||||
typedef struct {
|
||||
Elf32_Word p_type; /* segment type */
|
||||
Elf32_Off p_offset; /* segment offset */
|
||||
Elf32_Addr p_vaddr; /* virtual address of segment */
|
||||
Elf32_Addr p_paddr; /* physical address - ignored? */
|
||||
Elf32_Word p_filesz; /* number of bytes in file for seg. */
|
||||
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
|
||||
Elf32_Word p_flags; /* flags */
|
||||
Elf32_Word p_align; /* memory alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Half p_type; /* entry type */
|
||||
Elf64_Half p_flags; /* flags */
|
||||
Elf64_Off p_offset; /* offset */
|
||||
Elf64_Addr p_vaddr; /* virtual address */
|
||||
Elf64_Addr p_paddr; /* physical address */
|
||||
Elf64_Xword p_filesz; /* file size */
|
||||
Elf64_Xword p_memsz; /* memory size */
|
||||
Elf64_Xword p_align; /* memory & file alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* Segment types - p_type */
|
||||
#define PT_NULL 0 /* unused */
|
||||
#define PT_LOAD 1 /* loadable segment */
|
||||
#define PT_DYNAMIC 2 /* dynamic linking section */
|
||||
#define PT_INTERP 3 /* the RTLD */
|
||||
#define PT_NOTE 4 /* auxiliary information */
|
||||
#define PT_SHLIB 5 /* reserved - purpose undefined */
|
||||
#define PT_PHDR 6 /* program header */
|
||||
#define PT_NUM 7 /* Number of segment types */
|
||||
#define PT_LOOS 0x60000000 /* reserved range for OS */
|
||||
#define PT_HIOS 0x6fffffff /* specific segment types */
|
||||
#define PT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define PT_HIPROC 0x7fffffff /* specific segment types */
|
||||
|
||||
/* Segment flags - p_flags */
|
||||
#define PF_X 0x1 /* Executable */
|
||||
#define PF_W 0x2 /* Writable */
|
||||
#define PF_R 0x4 /* Readable */
|
||||
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific segment flags */
|
||||
|
||||
/* Dynamic structure */
|
||||
typedef struct {
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Xword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf64_Addr d_ptr;
|
||||
Elf64_Xword d_val;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* Dynamic Array Tags - d_tag */
|
||||
#define DT_NULL 0 /* marks end of _DYNAMIC array */
|
||||
#define DT_NEEDED 1 /* string table offset of needed lib */
|
||||
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
|
||||
#define DT_PLTGOT 3 /* address PLT/GOT */
|
||||
#define DT_HASH 4 /* address of symbol hash table */
|
||||
#define DT_STRTAB 5 /* address of string table */
|
||||
#define DT_SYMTAB 6 /* address of symbol table */
|
||||
#define DT_RELA 7 /* address of relocation table */
|
||||
#define DT_RELASZ 8 /* size of relocation table */
|
||||
#define DT_RELAENT 9 /* size of relocation entry */
|
||||
#define DT_STRSZ 10 /* size of string table */
|
||||
#define DT_SYMENT 11 /* size of symbol table entry */
|
||||
#define DT_INIT 12 /* address of initialization func. */
|
||||
#define DT_FINI 13 /* address of termination function */
|
||||
#define DT_SONAME 14 /* string table offset of shared obj */
|
||||
#define DT_RPATH 15 /* string table offset of library
|
||||
search path */
|
||||
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
|
||||
#define DT_REL 17 /* address of rel. tbl. w addends */
|
||||
#define DT_RELSZ 18 /* size of DT_REL relocation table */
|
||||
#define DT_RELENT 19 /* size of DT_REL relocation entry */
|
||||
#define DT_PLTREL 20 /* PLT referenced relocation entry */
|
||||
#define DT_DEBUG 21 /* bugger */
|
||||
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
|
||||
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
|
||||
#define DT_BIND_NOW 24 /* Bind now regardless of env setting */
|
||||
#define DT_NUM 25 /* Number used. */
|
||||
#define DT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
|
||||
|
||||
/* Standard ELF hashing function */
|
||||
unsigned int elf_hash(const char *name);
|
||||
|
||||
/*
|
||||
* Note Definitions
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word namesz;
|
||||
Elf32_Word descsz;
|
||||
Elf32_Word type;
|
||||
} Elf32_Note;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Half namesz;
|
||||
Elf64_Half descsz;
|
||||
Elf64_Half type;
|
||||
} Elf64_Note;
|
||||
|
||||
/*
|
||||
* XXX - these _KERNEL items aren't part of the ABI!
|
||||
*/
|
||||
#if defined(_KERNEL) || defined(_DYN_LOADER)
|
||||
|
||||
#define ELF32_NO_ADDR ((u_long) ~0) /* Indicates addr. not yet filled in */
|
||||
#define ELF_AUX_ENTRIES 8 /* Size of aux array passed to loader */
|
||||
|
||||
typedef struct {
|
||||
Elf32_Sword au_id; /* 32-bit id */
|
||||
Elf32_Word au_v; /* 32-bit value */
|
||||
} Aux32Info;
|
||||
|
||||
#define ELF64_NO_ADDR ((__uint64_t) ~0)/* Indicates addr. not yet filled in */
|
||||
#define ELF64_AUX_ENTRIES 8 /* Size of aux array passed to loader */
|
||||
|
||||
typedef struct {
|
||||
Elf64_Shalf au_id; /* 32-bit id */
|
||||
Elf64_Xword au_v; /* 64-bit id */
|
||||
} Aux64Info;
|
||||
|
||||
enum AuxID {
|
||||
AUX_null = 0,
|
||||
AUX_ignore = 1,
|
||||
AUX_execfd = 2,
|
||||
AUX_phdr = 3, /* &phdr[0] */
|
||||
AUX_phent = 4, /* sizeof(phdr[0]) */
|
||||
AUX_phnum = 5, /* # phdr entries */
|
||||
AUX_pagesz = 6, /* PAGESIZE */
|
||||
AUX_base = 7, /* ld.so base addr */
|
||||
AUX_flags = 8, /* processor flags */
|
||||
AUX_entry = 9, /* a.out entry */
|
||||
AUX_sun_uid = 2000, /* euid */
|
||||
AUX_sun_ruid = 2001, /* ruid */
|
||||
AUX_sun_gid = 2002, /* egid */
|
||||
AUX_sun_rgid = 2003 /* rgid */
|
||||
};
|
||||
|
||||
struct elf_args {
|
||||
u_long arg_entry; /* program entry point */
|
||||
u_long arg_interp; /* Interpreter load address */
|
||||
u_long arg_phaddr; /* program header address */
|
||||
u_long arg_phentsize; /* Size of program header */
|
||||
u_long arg_phnum; /* Number of program headers */
|
||||
u_long arg_os; /* OS tag */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
|
||||
#define ELFSIZE ARCH_ELFSIZE
|
||||
#endif
|
||||
|
||||
#if defined(ELFSIZE)
|
||||
#define CONCAT(x,y) __CONCAT(x,y)
|
||||
#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
|
||||
#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
|
||||
#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#endif
|
||||
|
||||
#if defined(ELFSIZE) && (ELFSIZE == 32)
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_RelA Elf32_Rela
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Half Elf32_Half
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Note Elf32_Note
|
||||
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
#define ELF_R_INFO ELF32_R_INFO
|
||||
#define ELFCLASS ELFCLASS32
|
||||
|
||||
#define ELF_ST_BIND ELF32_ST_BIND
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
#define ELF_ST_INFO ELF32_ST_INFO
|
||||
|
||||
#define AuxInfo Aux32Info
|
||||
#elif defined(ELFSIZE) && (ELFSIZE == 64)
|
||||
#define Elf_Ehdr Elf64_Ehdr
|
||||
#define Elf_Phdr Elf64_Phdr
|
||||
#define Elf_Shdr Elf64_Shdr
|
||||
#define Elf_Sym Elf64_Sym
|
||||
#define Elf_Rel Elf64_Rel
|
||||
#define Elf_RelA Elf64_Rela
|
||||
#define Elf_Dyn Elf64_Dyn
|
||||
#define Elf_Half Elf64_Half
|
||||
#define Elf_Word Elf64_Word
|
||||
#define Elf_Sword Elf64_Sword
|
||||
#define Elf_Addr Elf64_Addr
|
||||
#define Elf_Off Elf64_Off
|
||||
#define Elf_Nhdr Elf64_Nhdr
|
||||
#define Elf_Note Elf64_Note
|
||||
|
||||
#define ELF_R_SYM ELF64_R_SYM
|
||||
#define ELF_R_TYPE ELF64_R_TYPE
|
||||
#define ELF_R_INFO ELF64_R_INFO
|
||||
#define ELFCLASS ELFCLASS64
|
||||
|
||||
#define ELF_ST_BIND ELF64_ST_BIND
|
||||
#define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
#define ELF_ST_INFO ELF64_ST_INFO
|
||||
|
||||
#define AuxInfo Aux64Info
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef _KERN_DO_ELF64
|
||||
int exec_elf64_makecmds(struct proc *, struct exec_package *);
|
||||
void *elf64_copyargs(struct exec_package *, struct ps_strings *,
|
||||
void *, void *);
|
||||
int exec_elf64_fixup(struct proc *, struct exec_package *);
|
||||
char *elf64_check_brand(Elf64_Ehdr *);
|
||||
int elf64_os_pt_note(struct proc *, struct exec_package *, Elf64_Ehdr *,
|
||||
char *, size_t, size_t);
|
||||
#endif
|
||||
#ifdef _KERN_DO_ELF
|
||||
int exec_elf32_makecmds(struct proc *, struct exec_package *);
|
||||
void *elf32_copyargs(struct exec_package *, struct ps_strings *,
|
||||
void *, void *);
|
||||
int exec_elf32_fixup(struct proc *, struct exec_package *);
|
||||
char *elf32_check_brand(Elf32_Ehdr *);
|
||||
int elf32_os_pt_note(struct proc *, struct exec_package *, Elf32_Ehdr *,
|
||||
char *, size_t, size_t);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
|
||||
|
||||
#ifndef DT_INIT_ARRAY
|
||||
#define DT_INIT_ARRAY 25
|
||||
#endif
|
||||
|
||||
#ifndef DT_FINI_ARRAY
|
||||
#define DT_FINI_ARRAY 26
|
||||
#endif
|
||||
|
||||
#ifndef DT_INIT_ARRAYSZ
|
||||
#define DT_INIT_ARRAYSZ 27
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _SYS_EXEC_ELF_H_ */
|
388
User/programmer/elf_file.c
Normal file
388
User/programmer/elf_file.c
Normal file
@ -0,0 +1,388 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : elf文件解码模块
|
||||
* 文件名称 : elf_file.c
|
||||
* 版 本 : V1.0
|
||||
* 说 明 : 用于解码KEIL中FLM算法文件,提取加载到CPU RAM的代码。
|
||||
* FLM文件中的字符串表和符号表长度不能超过4096。
|
||||
*
|
||||
* 修改记录 :
|
||||
* 版本号 日期 作者 说明
|
||||
* V1.0 2019-12-29 armfly 正式发布
|
||||
*
|
||||
* Copyright (C), 2019-2030, 安富莱电子 www.armfly.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#include "bsp.h"
|
||||
#include "file_lib.h"
|
||||
#include "elf_file.h"
|
||||
#include "elf.h"
|
||||
#include "SWD_flash.h"
|
||||
#include "swd_host.h"
|
||||
|
||||
|
||||
/*
|
||||
Flash Programming Functions (Called by FlashOS)
|
||||
extern int Init (unsigned long adr, // Initialize Flash
|
||||
unsigned long clk,
|
||||
unsigned long fnc);
|
||||
extern int UnInit (unsigned long fnc); // De-initialize Flash
|
||||
extern int BlankCheck (unsigned long adr, // Blank Check
|
||||
unsigned long sz,
|
||||
unsigned char pat);
|
||||
extern int EraseChip (void); // Erase complete Device
|
||||
extern int EraseSector (unsigned long adr); // Erase Sector Function
|
||||
extern int ProgramPage (unsigned long adr, // Program Page Function
|
||||
unsigned long sz,
|
||||
unsigned char *buf);
|
||||
extern unsigned long Verify (unsigned long adr, // Verify Function
|
||||
unsigned long sz,
|
||||
unsigned char *buf);
|
||||
*/
|
||||
|
||||
const char *strFuncName[FUNC_NUM] = {"FlashDevice", "Init", "UnInit", "BlankCheck",
|
||||
"EraseChip", "EraseSector", "ProgramPage", "Verify", "STM32_CRC32"};
|
||||
|
||||
FLM_PARSE_T g_tFLM;
|
||||
|
||||
#define ALGO_RAM_ADDR 0x2000000
|
||||
#define ALGO_RAM_SIZE 0x1000
|
||||
|
||||
program_target_t flash_algo;
|
||||
|
||||
ELF_RAM_T g_AlgoRam;
|
||||
|
||||
static uint8_t ELF_FillToAlgo(char *_path, program_target_t *_algo);
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ELF_ParseFile
|
||||
* 功能说明: 解析elf文件. 使用了 FsReadBuf[4096]全部变量做缓冲区。解析结果放到全局变量g_tFLM
|
||||
* 形 参: _path : 文件路径
|
||||
* 返 回 值: 0 = ok, 其他值表示错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
uint8_t ELF_ParseFile(char *_path)
|
||||
{
|
||||
uint32_t bytes;
|
||||
uint32_t i,j;
|
||||
char *p;
|
||||
uint32_t StrFoud[FUNC_NUM] = {0};
|
||||
uint32_t StrIdx[FUNC_NUM] = {0};
|
||||
Elf_Ehdr Ehdr;
|
||||
Elf_Phdr *pPhdr;
|
||||
Elf_Shdr *pShdr;
|
||||
Elf_Sym *pSym;
|
||||
|
||||
Elf_Shdr ShdrSym; /* 符号表头 */
|
||||
Elf_Shdr ShdrStr; /* 字符串表头 */
|
||||
|
||||
/* 解析结果先全部清零 */
|
||||
for (i = 0; i < LOAD_NUM; i++)
|
||||
{
|
||||
g_tFLM.Load[i].Valid = 0;
|
||||
g_tFLM.Load[i].Offset = 0;
|
||||
g_tFLM.Load[i].Addr = 0;
|
||||
g_tFLM.Load[i].Size = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < FUNC_NUM; i++)
|
||||
{
|
||||
g_tFLM.Func[i].Valid = 0;
|
||||
g_tFLM.Func[i].Offset = 0;
|
||||
g_tFLM.Func[i].Size = 0;
|
||||
}
|
||||
|
||||
/* 解析文件头部 ELF Header */
|
||||
bytes = ReadFileToMem(_path, 0, FsReadBuf, 52);
|
||||
if (bytes != 52)
|
||||
{
|
||||
goto err; /* 读文件错误 */
|
||||
}
|
||||
memcpy((char *)&Ehdr, FsReadBuf, sizeof(Elf_Ehdr));
|
||||
if (IS_ELF(Ehdr) == 0)
|
||||
{
|
||||
goto err; /* 不是ELF文件 */
|
||||
}
|
||||
|
||||
if (Ehdr.e_type != ET_EXEC)
|
||||
{
|
||||
goto err; /* 不是可执行的镜像文件 */
|
||||
}
|
||||
|
||||
/* 解析程序头部(Program Header) - 2段 */
|
||||
if (Ehdr.e_phnum > LOAD_NUM)
|
||||
{
|
||||
goto err; /* Program Header 个数过大 */
|
||||
}
|
||||
bytes = ReadFileToMem(_path, Ehdr.e_phoff, FsReadBuf, Ehdr.e_phnum * 32);
|
||||
if (bytes != Ehdr.e_phnum * 32)
|
||||
{
|
||||
goto err; /* 读文件错误 */
|
||||
}
|
||||
|
||||
for (i = 0; i < Ehdr.e_phnum; i++)
|
||||
{
|
||||
pPhdr = (Elf_Phdr *)(FsReadBuf + i * 32);
|
||||
if (pPhdr->p_type == PT_LOAD)
|
||||
{
|
||||
g_tFLM.Load[i].Valid = 1;
|
||||
g_tFLM.Load[i].Offset = pPhdr->p_offset;
|
||||
g_tFLM.Load[i].Addr = pPhdr->p_vaddr;
|
||||
g_tFLM.Load[i].Size = pPhdr->p_filesz;
|
||||
}
|
||||
}
|
||||
|
||||
/* 解析节区头部 (Sections Header) */
|
||||
if (Ehdr.e_shnum < 25)
|
||||
{
|
||||
uint8_t found = 0;
|
||||
|
||||
bytes = ReadFileToMem(_path, Ehdr.e_shoff, FsReadBuf, 40 * Ehdr.e_shnum);
|
||||
|
||||
/* 先查找符号表 */
|
||||
for (i = 0; i < Ehdr.e_shnum; i++)
|
||||
{
|
||||
pShdr = (Elf_Shdr *)(FsReadBuf + 40 * i);
|
||||
if (pShdr->sh_type == SHT_SYMTAB)
|
||||
{
|
||||
memcpy((char *)&ShdrSym, (char *)pShdr, sizeof(Elf_Shdr));
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found == 0)
|
||||
{
|
||||
goto err; /* 未找到符号表 */
|
||||
}
|
||||
|
||||
/* 查找符号表对应的字符串表 (ELF文件中可能有多个字符串表)*/
|
||||
if (ShdrSym.sh_link >= Ehdr.e_shnum)
|
||||
{
|
||||
goto err; /* 未找到字符串表 */
|
||||
}
|
||||
|
||||
pShdr = (Elf_Shdr *)(FsReadBuf + 40 * ShdrSym.sh_link);
|
||||
if (pShdr->sh_type == SHT_STRTAB)
|
||||
{
|
||||
memcpy((char *)&ShdrStr, (char *)pShdr, sizeof(Elf_Shdr));
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err; /* 未找到字符串表 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err; /* Sections个数过大 */;
|
||||
}
|
||||
|
||||
/* 字符串表 */
|
||||
if (ShdrStr.sh_size < sizeof(FsReadBuf))
|
||||
{
|
||||
bytes = ReadFileToMem(_path, ShdrStr.sh_offset, FsReadBuf, ShdrStr.sh_size);
|
||||
if (bytes == ShdrStr.sh_size)
|
||||
{
|
||||
p = FsReadBuf;
|
||||
for (i = 0; i < bytes - 1; i++)
|
||||
{
|
||||
if (*p++ == 0)
|
||||
{
|
||||
for (j = 0; j < FUNC_NUM; j++)
|
||||
{
|
||||
if (strcmp(p, strFuncName[j]) == 0)
|
||||
{
|
||||
StrFoud[j] = 1;
|
||||
StrIdx[j] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err; /* 读文件失败 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto err; /* 字符串表过大 */
|
||||
}
|
||||
|
||||
/* 解析符号表 */
|
||||
if (ShdrSym.sh_size < sizeof(FsReadBuf))
|
||||
{
|
||||
bytes = ReadFileToMem(_path, ShdrSym.sh_offset, FsReadBuf, ShdrSym.sh_size);
|
||||
|
||||
for (i = 0; i < bytes / sizeof(Elf_Sym); i++)
|
||||
{
|
||||
for (j = 0; j < FUNC_NUM; j++)
|
||||
{
|
||||
pSym = (Elf_Sym *)(FsReadBuf + 16 * i);
|
||||
if (pSym->st_name == StrIdx[j] && StrFoud[j] == 1)
|
||||
{
|
||||
g_tFLM.Func[j].Valid = 1;
|
||||
g_tFLM.Func[j].Offset = pSym->st_value;
|
||||
g_tFLM.Func[j].Size = pSym->st_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 符号表过大 */
|
||||
}
|
||||
|
||||
/* 解析器件信息 */
|
||||
{
|
||||
bytes = ReadFileToMem(_path, g_tFLM.Func[IDX_FlashDevice].Offset + 52, FsReadBuf, sizeof(FlashDevice_T));
|
||||
memcpy((char *)&g_tFLM.Device, FsReadBuf, sizeof(FlashDevice_T));
|
||||
}
|
||||
|
||||
if (ELF_FillToAlgo(_path, &flash_algo) == 0)
|
||||
{
|
||||
return 0; /* 解析成功 */
|
||||
}
|
||||
err:
|
||||
return 1; /* 解析失败 */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ELF_FillToAlgo
|
||||
* 功能说明: 解析elf文件. 使用了 FsReadBuf[4096]全部变量做缓冲区。解析结果放到全局变量g_tFLM
|
||||
* 形 参: _path : 文件路径
|
||||
* 返 回 值: 0 = ok, 其他值表示错误
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
const uint32_t BLOB_HEADER[] = {0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2};
|
||||
static uint8_t ELF_FillToAlgo(char *_path, program_target_t *_algo)
|
||||
{
|
||||
//typedef struct {
|
||||
// uint32_t breakpoint;
|
||||
// uint32_t static_base;
|
||||
// uint32_t stack_pointer;
|
||||
//} program_syscall_t;
|
||||
|
||||
//typedef struct {
|
||||
// const uint32_t init;
|
||||
// const uint32_t uninit;
|
||||
// const uint32_t erase_chip;
|
||||
// const uint32_t erase_sector;
|
||||
// const uint32_t program_page;
|
||||
// const program_syscall_t sys_call_s;
|
||||
// const uint32_t program_buffer;
|
||||
// const uint32_t algo_start;
|
||||
// const uint32_t algo_size;
|
||||
// const uint32_t *algo_blob;
|
||||
// const uint32_t program_buffer_size;
|
||||
//} program_target_t;
|
||||
|
||||
//typedef struct {
|
||||
// const uint32_t start;
|
||||
// const uint32_t size;
|
||||
//} sector_info_t;
|
||||
|
||||
// IDX_FlashDevice = 0,
|
||||
// IDX_Init,
|
||||
// IDX_UnInit,
|
||||
// IDX_BlankCheck,
|
||||
// IDX_EraseChip,
|
||||
// IDX_EraseSector,
|
||||
// IDX_ProgramPage,
|
||||
// IDX_Verify,
|
||||
|
||||
//static const uint32_t flash_code[] = {
|
||||
// 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
|
||||
// 0x4603B510, 0x4C442000, 0x48446020, 0x48446060, 0x46206060, 0xF01069C0, 0xD1080F04, 0x5055F245,
|
||||
// 0x60204C40, 0x60602006, 0x70FFF640, 0x200060A0, 0x4601BD10, 0x69004838, 0x0080F040, 0x61104A36,
|
||||
// 0x47702000, 0x69004834, 0x0004F040, 0x61084932, 0x69004608, 0x0040F040, 0xE0036108, 0x20AAF64A,
|
||||
// 0x60084930, 0x68C0482C, 0x0F01F010, 0x482AD1F6, 0xF0206900, 0x49280004, 0x20006108, 0x46014770,
|
||||
// 0x69004825, 0x0002F040, 0x61104A23, 0x61414610, 0xF0406900, 0x61100040, 0xF64AE003, 0x4A2120AA,
|
||||
// 0x481D6010, 0xF01068C0, 0xD1F60F01, 0x6900481A, 0x0002F020, 0x61104A18, 0x47702000, 0x4603B510,
|
||||
// 0xF0201C48, 0xE0220101, 0x69004813, 0x0001F040, 0x61204C11, 0x80188810, 0x480FBF00, 0xF01068C0,
|
||||
// 0xD1FA0F01, 0x6900480C, 0x0001F020, 0x61204C0A, 0x68C04620, 0x0F14F010, 0x4620D006, 0xF04068C0,
|
||||
// 0x60E00014, 0xBD102001, 0x1C921C9B, 0x29001E89, 0x2000D1DA, 0x0000E7F7, 0x40022000, 0x45670123,
|
||||
// 0xCDEF89AB, 0x40003000, 0x00000000
|
||||
//};
|
||||
|
||||
//const program_target_t flash_algo = {
|
||||
// 0x20000021, // Init
|
||||
// 0x20000053, // UnInit
|
||||
// 0x20000065, // EraseChip
|
||||
// 0x2000009F, // EraseSector
|
||||
// 0x200000DD, // ProgramPage
|
||||
|
||||
// // BKPT : start of blob + 1
|
||||
// // RSB : address to access global/static data
|
||||
// // RSP : stack pointer
|
||||
// {
|
||||
// 0x20000001,
|
||||
// 0x20000C00,
|
||||
// 0x20001000
|
||||
// },
|
||||
|
||||
// 0x20000400, // mem buffer location
|
||||
// 0x20000000, // location to write prog_blob in target RAM
|
||||
// sizeof(flash_code), // prog_blob size
|
||||
// flash_code, // address of prog_blob
|
||||
// 0x00000400, // ram_to_flash_bytes_to_be_written
|
||||
//};
|
||||
uint32_t bytes;
|
||||
|
||||
memcpy(FsReadBuf, (char *)BLOB_HEADER, 4 * 8);
|
||||
|
||||
if (g_tFLM.Load[0].Size + 32 > sizeof(FsReadBuf))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
bytes = ReadFileToMem(_path, g_tFLM.Load[0].Offset, FsReadBuf + 32, g_tFLM.Load[0].Size);
|
||||
if (bytes != g_tFLM.Load[0].Size)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
_algo->init = g_tFLM.Func[IDX_Init].Offset + g_AlgoRam.Addr + 32;
|
||||
_algo->uninit = g_tFLM.Func[IDX_UnInit].Offset + g_AlgoRam.Addr + 32;
|
||||
_algo->erase_chip = g_tFLM.Func[IDX_EraseChip].Offset + g_AlgoRam.Addr + 32;
|
||||
_algo->erase_sector = g_tFLM.Func[IDX_EraseSector].Offset + g_AlgoRam.Addr + 32;
|
||||
_algo->program_page = g_tFLM.Func[IDX_ProgramPage].Offset + g_AlgoRam.Addr + 32;
|
||||
|
||||
_algo->verify = 0;
|
||||
if (g_tFLM.Func[IDX_Verify].Offset > 0)
|
||||
{
|
||||
_algo->verify = g_tFLM.Func[IDX_Verify].Offset + g_AlgoRam.Addr + 32;
|
||||
}
|
||||
|
||||
_algo->check_blank = 0;
|
||||
if (g_tFLM.Func[IDX_BlankCheck].Offset > 0)
|
||||
{
|
||||
_algo->check_blank = g_tFLM.Func[IDX_BlankCheck].Offset + g_AlgoRam.Addr + 32;
|
||||
}
|
||||
|
||||
_algo->cacul_crc32 = 0;
|
||||
if (g_tFLM.Func[IDX_CaculCRC32].Offset > 0)
|
||||
{
|
||||
_algo->cacul_crc32 = g_tFLM.Func[IDX_CaculCRC32].Offset + g_AlgoRam.Addr + 32;
|
||||
}
|
||||
|
||||
_algo->sys_call_s.breakpoint = g_AlgoRam.Addr + 1;
|
||||
_algo->sys_call_s.static_base = g_AlgoRam.Addr + 0xC00;
|
||||
_algo->sys_call_s.stack_pointer = g_AlgoRam.Addr + ALGO_RAM_SIZE;
|
||||
|
||||
|
||||
_algo->algo_start = g_AlgoRam.Addr + g_tFLM.Load[0].Addr;
|
||||
_algo->algo_size = g_tFLM.Load[0].Size + 32;
|
||||
_algo->algo_blob = (uint32_t *)FsReadBuf;
|
||||
_algo->program_buffer_size = g_tFLM.Device.szPage;
|
||||
_algo->program_buffer = g_AlgoRam.Addr + _algo->algo_size;
|
||||
return 0; /* 解析成功 */
|
||||
|
||||
err:
|
||||
return 1; /* 解析失败 */
|
||||
}
|
||||
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
76
User/programmer/elf_file.h
Normal file
76
User/programmer/elf_file.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : elf文件解析模块
|
||||
* 文件名称 : elf_file.h
|
||||
* 说 明 : 头文件
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __ELF_FILE_H_
|
||||
#define __ELF_FILE_H_
|
||||
|
||||
#include "FlashOS.h"
|
||||
|
||||
#define FUNC_NUM 9 /* 全局符号个数(函数和一个常量数组) */
|
||||
#define LOAD_NUM 4 /* 需要加载到RAM的段个数 */
|
||||
|
||||
#define SECTOR_INFO_NUM 32 /* 需要加载到RAM的段个数 */
|
||||
|
||||
enum
|
||||
{
|
||||
IDX_FlashDevice = 0,
|
||||
IDX_Init,
|
||||
IDX_UnInit,
|
||||
IDX_BlankCheck,
|
||||
IDX_EraseChip,
|
||||
IDX_EraseSector,
|
||||
IDX_ProgramPage,
|
||||
IDX_Verify,
|
||||
IDX_CaculCRC32,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Valid;
|
||||
uint32_t Offset;
|
||||
uint32_t Size;
|
||||
}
|
||||
ELF_FUNC_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Valid;
|
||||
uint32_t Offset;
|
||||
uint32_t Addr;
|
||||
uint32_t Size;
|
||||
}
|
||||
ELF_LOAD_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Valid;
|
||||
uint32_t Addr;
|
||||
uint32_t Size;
|
||||
}
|
||||
ELF_RAM_T;
|
||||
|
||||
/* FLM文件分析结构 */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t FileOk;
|
||||
|
||||
ELF_LOAD_T Load[LOAD_NUM];
|
||||
|
||||
ELF_FUNC_T Func[FUNC_NUM];
|
||||
|
||||
FlashDevice_T Device;
|
||||
}FLM_PARSE_T;
|
||||
|
||||
extern FLM_PARSE_T g_tFLM;
|
||||
extern ELF_RAM_T g_AlgoRam;
|
||||
|
||||
uint8_t ELF_ParseFile(char *_path);
|
||||
|
||||
#endif
|
96
User/programmer/falsh_error.c
Normal file
96
User/programmer/falsh_error.c
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file error.c
|
||||
* @brief collection of known errors and accessor for the friendly string
|
||||
*/
|
||||
|
||||
#include "error.h"
|
||||
|
||||
static const char *const error_message[] = {
|
||||
|
||||
/* Shared errors */
|
||||
|
||||
// ERROR_SUCCESS
|
||||
"Operation was successful",
|
||||
// ERROR_FAILURE
|
||||
"An error has occurred",
|
||||
// ERROR_INTERNAL
|
||||
"An internal error has occurred",
|
||||
|
||||
|
||||
/* Target flash errors */
|
||||
|
||||
// ERROR_RESET
|
||||
"The interface firmware FAILED to reset/halt the target MCU",
|
||||
// ERROR_ALGO_DL
|
||||
"The interface firmware FAILED to download the flash programming algorithms to the target MCU",
|
||||
// ERROR_ALGO_DATA_SEQ
|
||||
"The interface firmware FAILED to download the flash data contents to be programmed",
|
||||
// ERROR_INIT
|
||||
"The interface firmware FAILED to initialize the target MCU",
|
||||
// ERROR_SECURITY_BITS
|
||||
"The interface firmware ABORTED programming. Image is trying to set security bits",
|
||||
// ERROR_UNLOCK
|
||||
"The interface firmware FAILED to unlock the target for programming",
|
||||
// ERROR_ERASE_SECTOR
|
||||
"Flash algorithm erase sector command FAILURE",
|
||||
// ERROR_ERASE_ALL
|
||||
"Flash algorithm erase all command FAILURE",
|
||||
// ERROR_WRITE
|
||||
"Flash algorithm write command FAILURE",
|
||||
};
|
||||
|
||||
static error_type_t error_type[] = {
|
||||
|
||||
/* These should always stay the same for each error type. */
|
||||
|
||||
// ERROR_SUCCESS
|
||||
0,
|
||||
// ERROR_FAILURE
|
||||
ERROR_TYPE_INTERNAL,
|
||||
// ERROR_INTERNAL
|
||||
ERROR_TYPE_INTERNAL,
|
||||
|
||||
|
||||
/* Target flash errors */
|
||||
|
||||
// ERROR_RESET
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_ALGO_DL
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_ALGO_DATA_SEQ
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_INIT
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_SECURITY_BITS
|
||||
ERROR_TYPE_USER,
|
||||
// ERROR_UNLOCK
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_ERASE_SECTOR
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_ERASE_ALL
|
||||
ERROR_TYPE_TARGET,
|
||||
// ERROR_WRITE
|
||||
ERROR_TYPE_TARGET,
|
||||
};
|
||||
|
||||
const char *error_get_string(error_t error)
|
||||
{
|
||||
const char *msg = 0;
|
||||
|
||||
if (error < ERROR_COUNT) {
|
||||
msg = error_message[error];
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
error_type_t error_get_type(error_t error)
|
||||
{
|
||||
error_type_t type = ERROR_TYPE_INTERNAL;
|
||||
|
||||
if (error < ERROR_COUNT) {
|
||||
type = error_type[error];
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
44
User/programmer/falsh_error.h
Normal file
44
User/programmer/falsh_error.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
|
||||
// Keep in sync with the lists error_message and error_type
|
||||
typedef enum {
|
||||
/* Shared errors */
|
||||
ERROR_SUCCESS = 0,
|
||||
ERROR_FAILURE,
|
||||
ERROR_INTERNAL,
|
||||
|
||||
/* Target flash errors */
|
||||
ERROR_RESET,
|
||||
ERROR_ALGO_DL,
|
||||
ERROR_ALGO_DATA_SEQ,
|
||||
ERROR_INIT,
|
||||
ERROR_SECURITY_BITS,
|
||||
ERROR_UNLOCK,
|
||||
ERROR_ERASE_SECTOR,
|
||||
ERROR_ERASE_ALL,
|
||||
ERROR_WRITE,
|
||||
|
||||
// Add new values here
|
||||
|
||||
ERROR_COUNT
|
||||
} error_t;
|
||||
|
||||
|
||||
typedef unsigned char error_type_t;
|
||||
|
||||
#define ERROR_TYPE_INTERNAL 0x1
|
||||
#define ERROR_TYPE_TRANSIENT 0x2
|
||||
#define ERROR_TYPE_USER 0x4
|
||||
#define ERROR_TYPE_TARGET 0x8
|
||||
|
||||
#define ERROR_TYPE_MASK 0xF
|
||||
|
||||
|
||||
const char *error_get_string(error_t error);
|
||||
|
||||
error_type_t error_get_type(error_t error);
|
||||
|
||||
|
||||
#endif
|
39
User/programmer/flash_blob.h
Normal file
39
User/programmer/flash_blob.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef FLASH_BLOB_H
|
||||
#define FLASH_BLOB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t breakpoint;
|
||||
uint32_t static_base;
|
||||
uint32_t stack_pointer;
|
||||
} program_syscall_t;
|
||||
|
||||
/* armfly : const 属性全部去掉了*/
|
||||
typedef struct {
|
||||
uint32_t init;
|
||||
uint32_t uninit;
|
||||
uint32_t erase_chip;
|
||||
uint32_t erase_sector;
|
||||
uint32_t program_page;
|
||||
|
||||
uint32_t verify;
|
||||
uint32_t check_blank;
|
||||
uint32_t cacul_crc32;
|
||||
|
||||
program_syscall_t sys_call_s;
|
||||
uint32_t program_buffer;
|
||||
uint32_t algo_start;
|
||||
uint32_t algo_size;
|
||||
uint32_t *algo_blob;
|
||||
uint32_t program_buffer_size;
|
||||
} program_target_t;
|
||||
|
||||
typedef struct {
|
||||
const uint32_t start;
|
||||
const uint32_t size;
|
||||
} sector_info_t;
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -14,30 +14,63 @@
|
||||
#ifndef __PROG_IF_H_
|
||||
#define __PROG_IF_H_
|
||||
|
||||
#define DEV_SYS 1
|
||||
#define DEV_GPIO 2
|
||||
#define DEV_TIM 3
|
||||
#define DEV_DAC 4
|
||||
#define DEV_ADC 5
|
||||
#define DEV_I2C 6
|
||||
#define DEV_SPI 7
|
||||
#define DEV_UART 8
|
||||
#define DEV_485 9
|
||||
#define DEV_CAN 10
|
||||
#define DEV_SWD 11
|
||||
/* 编程过程中输出的消息 */
|
||||
enum
|
||||
{
|
||||
PG_MSG_TEXT = 0, /* 输出文本 */
|
||||
PG_MSG_ERASE_PROGRESS, /* 擦除进度消息 */
|
||||
PG_MSG_PROG_PROGRESS, /* 编程进度消息 */
|
||||
PG_MSG_VERIFY_PROGRESS, /* 校验进度消息 */
|
||||
PG_MSG_TIME, /* 已运行时间,ms单位 */
|
||||
};
|
||||
|
||||
#define I2C_START (DEV_I2C + 00)
|
||||
#define I2C_STOP (DEV_I2C + 01)
|
||||
#define I2C_SEND_BYTE (DEV_I2C + 02)
|
||||
#define I2C_SEND_BYTES (DEV_I2C + 03)
|
||||
#define I2C_READ_BYTES (DEV_I2C + 04)
|
||||
typedef struct
|
||||
{
|
||||
char FilePath[128]; /* lua文件路径 */
|
||||
|
||||
uint32_t Time;
|
||||
|
||||
uint32_t EraseChipTime1;
|
||||
uint32_t EraseChipTime2;
|
||||
|
||||
uint8_t Err;
|
||||
|
||||
uint32_t FLMFuncTimeout; /* 执行算法函数超时时间。擦除整片时可能耗时20秒 */
|
||||
uint8_t FLMEraseChipFlag; /* 临时处理,正在擦除全片*/
|
||||
|
||||
void PG_Poll(void);
|
||||
uint8_t AutoStart; /* 检测到芯片后自动开始编程 */
|
||||
|
||||
int32_t NowProgCount; /* 编程次数。掉电清零 */
|
||||
|
||||
uint8_t UidEnable; /* 编程时是否填充UID */
|
||||
uint32_t UidAddr; /* 加密后的UID存储地址 */
|
||||
const char *UidData; /* UID数据缓冲区指针,由Lua生成 */
|
||||
uint16_t UidLen; /* UID数据缓冲区长度 */
|
||||
uint8_t UidBlank; /* 空标志 */
|
||||
|
||||
uint8_t UsrEnable; /* 编程时是否填充用户指定数据 */
|
||||
uint32_t UsrAddr; /* 用户数据存储地址 */
|
||||
const char *UsrData; /* 用户数据缓冲区指针,由Lua生成 */
|
||||
uint16_t UsrLen; /* 用户数据缓冲区长度 */
|
||||
uint8_t UsrBlank; /* 空标志 */
|
||||
|
||||
uint8_t SnEnable; /* 编程时是否填充SN */
|
||||
uint32_t SnAddr; /* SN数据存储地址 */
|
||||
const char *SnData; /* SN数据缓冲区指针,由Lua生成 */
|
||||
uint16_t SnLen; /* SN数据缓冲区长度 */
|
||||
uint8_t SndBlank; /* 空标志 */
|
||||
|
||||
}OFFLINE_PROG_T;
|
||||
|
||||
void PG_Install(uint16_t _addr, uint8_t *_buf, uint16_t _len, uint16_t _total_len);
|
||||
uint8_t PG_WaitRunCompleted(uint16_t _usTimeout);
|
||||
|
||||
extern uint8_t s_prog_ack_buf[2 * 1024];
|
||||
extern uint16_t s_prog_ack_len;
|
||||
extern OFFLINE_PROG_T g_tProg;
|
||||
|
||||
uint16_t PG_ProgFile(char *_Path, uint32_t _FlashAddr);
|
||||
|
||||
uint16_t PG_ProgBuf(uint32_t _FlashAddr, uint8_t *_DataBuf, uint32_t _BufLen, uint8_t _Mode);
|
||||
uint16_t PG_ProgBuf_OB(uint32_t _FlashAddr, uint8_t *_DataBuf, uint32_t _BufLen);
|
||||
|
||||
uint16_t PG_EraseChip(uint32_t _FlashAddr);
|
||||
void DispProgProgress(char *_str, float _progress);
|
||||
|
||||
#endif
|
||||
|
@ -119,6 +119,7 @@ void usbd_CloseCDC(void)
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
extern void bsp_DelayMS(uint32_t n);
|
||||
void usbd_OpenMassStorage(void)
|
||||
{
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user