LarduinoISP for LGT8FX8D SWD通信协议源码简析
LGT8FX8D/P系列的CPU可以指令级兼容avr芯片,引脚定义也相近.将avr的程序移植到LGT8FX8D/P只需作少量的修改,而且增强了一些性能,价格却更低,性价比高.
要将程序写入空片,其flash烧写方式与avr并不一样,需要专门的调试下载器.使用说明
在LarduinoISP for LGT8FX8D公开了份代码,其中实现了通过SWD接口实现LGT8FX8D的读写.我们通过阅读这份代码来看看通过SWD通信方式来实现flash烧写的过程.
SWD通信硬件要求
需使用的引脚:
引脚 | 传输方向 | 描述 |
---|---|---|
SWD | 输入与输出 | 用作传输数据比特,双向 |
SWC | 输出 | 用作时钟信号 |
RST | 输出 | SWD模式时RST拉低 |
SWD
对应PB5,SWC
对应PB4,RST
对应PB2
#define SWDIF_PIN PINB
#define SWDIF_DIR DDRB
#define SWDIF_PORT PORTB
#define SWDIF_CLK (1 << 5) // PB5
#define SWDIF_DAT (1 << 4) // PB4
#define SWDIF_RSTN (1 << 2) // PB2
SWD通信时序分析
所有时序的实现,由CPU操作IO口完成.
通信速率
在一个通信时钟周期会调用二次SWD_Delay()
即 12 ∗ 2 12*2 12∗2个NOP
指令,再加上设置SWC
SWD
电平的指令,总约需30个指令周期,在16MHz的系统时钟下,通信速率可达500Kbps.如果一个位输出中有更多的逻辑操作,则通信频率会更低一些.
#define SWD_Delay() do {\NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); \NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); \
} while(0);
//一个时钟周期的模拟SWC_CLR();SWD_Delay();SWD_CLR();SWD_Delay();SWC_SET();SWD_Delay();
通信时序
数据通信由起始位SWD_CLR
开始,然后是输出一个字节是由一串8比特数据加一个结束位SWD_SET
组成,如有多个字节输出,则中间结束位为SWD_CLR
,最后的结束位为SWD_SET
.每个字节的先输出最低位,再到最高位的顺序输出,即LSB First.
双向引脚SWD
输出数据时,在时钟SWC
低电平时改变SWD
输出数据,写入目标芯片会在SWC
的上升沿检测SWD
数据.
void SWD_WriteByte(uint8_t start, uint8_t data, uint8_t stop)
{volatile uint8_t cnt;if(start) {SWC_CLR();SWD_Delay();SWD_CLR();SWD_Delay();SWC_SET();SWD_Delay();}// send datafor(cnt = 0; cnt < 8; cnt++){SWC_CLR();if(data & 0x1) SWD_SET();else SWD_CLR();SWD_Delay();data >>= 1;SWC_SET();SWD_Delay();}SWC_CLR();if(stop) SWD_SET();else SWD_CLR();SWD_Delay();SWC_SET();SWD_Delay();
}
双向引脚SWD
输入数据时,在时钟SWC
高电平时设为输入并上拉,由写入目标芯片控制SWD
,在SWC
的下降沿检测SWD
数据.
uint8_t SWD_ReadByte(uint8_t start, uint8_t stop)
{volatile uint8_t cnt;volatile uint8_t bRes = 0;if(start){SWC_CLR();SWD_CLR();SWD_Delay();SWC_SET();SWD_Delay(); }SWD_IND();//SWD_Delay();for(cnt = 0; cnt < 8; cnt++){bRes >>= 1;SWC_CLR();SWD_Delay();if(SWDIF_PIN & SWDIF_DAT)bRes |= 0x80;SWC_SET();SWD_Delay();}SWD_OUD();SWC_CLR();if(stop) SWD_SET();else SWD_CLR();SWD_Delay();SWC_SET();SWD_Delay();return bRes;
}
一些操作需要通过一些时序才能完成,故有些需加上SWD_Idle
等待.
void SWD_Idle(uint8_t cnt)
{volatile uint8_t i;SWD_SET();for(i = 0; i < cnt; i++){SWC_CLR();SWD_Delay();SWC_SET();SWD_Delay();}
}
Flash写入相关
- 读取SWD ID
SWD_ReadSWDID()
- Unlock()操作,因芯片的保护机制,掉电再上电后,是不能通过SWD接口来读取Flash中的数据的,此
Unlock
操作相当于对芯片进行全芯片擦除,之后所读数据全部为0xff,并允许写入操作.
uint8_t SWD_UnLock()
{...SWD_UnLock0();SWD_EEE_UnlockTiming();SWD_UnLock1();delayus(100);SWD_UnLock0();delayus(100);SWD_UnLock1();
...
}
- 读取
Read()
,因flash为16位,参数addr
为word地址,每次读取两个字节,返回一个word数据
uint16_t SWD_EEE_Read(uint16_t addr)
{volatile uint8_t hbyte, lbyte;SWD_EEE_CSEQ(0x00, addr);SWD_EEE_CSEQ(0xa0, addr);SWD_WriteByte(1, 0xaa, 1);lbyte = SWD_ReadByte(1, 0);hbyte = SWD_ReadByte(0, 1);SWD_Idle(10);SWD_EEE_CSEQ(0x00, addr);return (hbyte << 8) | lbyte;
}
- 写入
write()
,因flash为16位,参数addr
为word地址,每次写入两个字节,即一个word数据
void SWD_EEE_Write(uint16_t data, uint16_t addr)
{volatile uint8_t ib;volatile uint8_t timout = 0x1f;SWD_EEE_CSEQ(0x00, addr);SWD_EEE_DSEQ(data);SWD_EEE_CSEQ(0x04, addr);SWD_EEE_CSEQ(0x84, addr);SWD_EEE_CSEQ(0x02, addr);do {delayus(50);ib = SWD_EEE_GetBusy();--timout;} while(ib == 1 && timout > 0);SWD_EEE_CSEQ(0x00, addr);
}
以上16位地址和数据输入输出均为低字节优先,然后再高字节,即little-endian模式.
LarduinoISP for LGT8FX8D SWD通信协议源码简析相关推荐
- 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析
目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...
- django源码简析——后台程序入口
django源码简析--后台程序入口 这一年一直在用云笔记,平时记录一些tips或者问题很方便,所以也就不再用博客进行记录,还是想把最近学习到的一些东西和大家作以分享,也能够对自己做一个总结.工作中主 ...
- (Ajax)axios源码简析(三)——请求与取消请求
传送门: axios源码简析(一)--axios入口文件 axios源码简析(二)--Axios类与拦截器 axios源码简析(三)--请求与取消请求 请求过程 在Axios.prototype.re ...
- java ArrayList 概述 与源码简析
ArrayList 概述 与源码简析 1 ArrayList 创建 ArrayList<String> list = new ArrayList<>(); //构造一个初始容量 ...
- Spring Boot源码简析 @EnableTransactionManagement
相关阅读 Spring Boot源码简析 事务管理 Spring Boot源码简析 @EnableAspectJAutoProxy Spring Boot源码简析 @EnableAsync Sprin ...
- ffmpeg实战教程(十三)iJKPlayer源码简析
要使用封装优化ijk就必须先了解ffmpeg,然后看ijk对ffmpeg的C层封装! 这是我看ijk源码时候的笔记,比较散乱.不喜勿喷~ ijk源码简析: 1.ijkplayer_jni.c 封装的播 ...
- 【Android项目】本地FM收音机开发及源码简析
[Android项目]本地FM收音机开发及源码简析 目录 1.概述 2.收音机的基本原理 3.收音机其他信息 RDS功能 4.Android开发FM收音机源码解析 5.App层如何设计本地FM应用 6 ...
- Log-Pilot 源码简析
Log-Pilot 源码简析 简单介绍 源码简析 Pilot结构体 Piloter接口 main函数 Pilot.Run Pilot.New Pilot.watch Pilot.processEven ...
- Lottie动画框架入门及源码简析
现在越来越多的APP中添加动画来提升用户体验,下面简单介绍下Airbnb开源的动画框架Lottie的使用 一.基本使用 首先添加依赖 compile 'com.airbnb.android:lotti ...
最新文章
- Atitit.研发管理---api版本号策略与版本控制
- 完美解决vue项目中弹出框滑动时,内部页面也跟着滑动问题
- shape的各种获取、更改以及设置方式辨析
- CST 使用注意事项【持续更新】
- JMF视频音频通信( 图+源码 )
- 省会城市房价地图,这9座新星城市正在悄然崛起
- 卡巴斯基终生免费使用方法
- Xen调度分析-RT
- aspen如何确定塔板数_Aspen Plus入门教程(3)-简捷法计算理论板数
- MAC jd-gui 安装
- SEO|解析关键词密度与分布
- 计算机能安装几个硬盘,一台电脑最多能接多少个硬盘?
- android+imei+为null,适合Android7.0以上(到9.0)系统,获取 关于手机--状态信息 (如:MAC,IMEI,IMSI,ICCID)...
- AppStore跳转链接
- 怎么制作公司网页教程【网站制作】
- Java 并发编程解析 | 如何正确理解Java领域中的多线程模型,主要用来解决什么问题?
- FXDD-点值获利计算
- 动态规划:高阶马尔科夫模型
- 【gitlab+jenkins+docker】第一节 基础环境介绍与准备
- 自学java怎么快速入门?
热门文章
- SQL--数据库的操作(DDL,DML,DQL)+使用命令查看当前数据库的存储位置(数据库版本查询)
- 为app添加动态gif背景
- 有没有大佬知道,有哪些可以在网页上自动填写账号密码并登录的方法?
- 如何关闭win7下的打开文件安全警告
- python摄像头拍照比对_如何使用Python控制摄像头拍照并发邮件?
- Program type already present问题解决
- 【GoDance搜索引擎】搜索引擎集群模块实现笔记
- 二分查找算法详解(经典二分和左右边界查找)
- Oracle服务器性能优化
- Python第六次学习例题---表、题:“三国演义”和“柯南系列41部合集”词云