增加脱机烧录功能

This commit is contained in:
armfly 2020-02-06 23:01:29 +08:00
parent 239d4fb5f0
commit 92c24f60b8
53 changed files with 7004 additions and 2148 deletions

View File

@ -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

View File

@ -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>

View File

@ -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

Binary file not shown.

View File

@ -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

View File

@ -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);

View File

@ -95,11 +95,11 @@ typedef struct
uint32_t TestWord; /* 测试单元用于检测eepromg功能 */
uint8_t NtcType; /* NTC热敏电阻类型 0 = 10K_B39501 = 100K_B3950 */
/* V2.04追加 */
uint8_t KeyToneEnable;
uint8_t UIStyle; /* UI风格 */
uint16_t LcdSleepTime; /* 屏保时间 */
uint8_t FileListFont24; /* 1表示24点阵显示文件列表0表示16点阵 */
} PARAM_T;
/* 模拟量校准参数 */

View 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) *********************************/

View 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

View File

@ -16,6 +16,9 @@
*/
#include "bsp.h"
#include "file_lib.h"
#include "lcd_menu.h"
#include "main.h"
#include "prog_if.h"
/*
1V7开发板的SD卡接口是用的SDMMC1AXI 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 1OK
*********************************************************************************************************
*/
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) *********************************/

View 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);

View File

@ -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();
}

View File

@ -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:

View File

@ -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键按下 */

View File

@ -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; /* 按键代码 */

View 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

View File

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

View File

@ -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);

View File

@ -44,6 +44,7 @@
#include "stm32h7xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>

View File

@ -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) *********************************/

View 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)
{

View File

@ -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 *)(&reg), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);;
}
// /* Reception of the data */
// if (HAL_QSPI_Receive(hqspi, (uint8_t *)(&reg), 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 *)(&reg), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);;
}
// /* Transmission of the data */
// if (HAL_QSPI_Transmit(hqspi, (uint8_t *)(&reg), 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);
}
//}
/*
*********************************************************************************************************

View File

@ -3,9 +3,8 @@
*
* : TFT液晶显示器驱动模块
* : bsp_tft_lcd.c
* : V4.2
* : 3.0 3.5 4.3 5.0 7.0.
* 3.0LCD内部驱动芯片型号有: SPFD5420AOTM4001AR61509V
* : 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);

View File

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

View File

@ -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字符串012ASCII字符.
* _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码串tab0-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 :
* : 1OK 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 编码非常简单。
011
UNICODE x0
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
* : 10
*********************************************************************************************************
*/
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) *********************************/

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

View File

@ -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

View File

@ -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程序9CPU的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) */

View File

@ -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:

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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结束这是字库数组结束标志 */

View File

@ -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个参数 */
{

View File

@ -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);

View File

@ -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个参数 */

View File

@ -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个参数 */

View File

@ -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 *)&reg_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) *********************************/

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

View 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
View 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
View 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) *********************************/

View 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

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

View 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

View 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

View File

@ -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

View File

@ -119,6 +119,7 @@ void usbd_CloseCDC(void)
* :
*********************************************************************************************************
*/
extern void bsp_DelayMS(uint32_t n);
void usbd_OpenMassStorage(void)
{
{