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位,参数addrword地址,每次读取两个字节,返回一个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通信协议源码简析相关推荐

  1. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  2. django源码简析——后台程序入口

    django源码简析--后台程序入口 这一年一直在用云笔记,平时记录一些tips或者问题很方便,所以也就不再用博客进行记录,还是想把最近学习到的一些东西和大家作以分享,也能够对自己做一个总结.工作中主 ...

  3. (Ajax)axios源码简析(三)——请求与取消请求

    传送门: axios源码简析(一)--axios入口文件 axios源码简析(二)--Axios类与拦截器 axios源码简析(三)--请求与取消请求 请求过程 在Axios.prototype.re ...

  4. java ArrayList 概述 与源码简析

    ArrayList 概述 与源码简析 1 ArrayList 创建 ArrayList<String> list = new ArrayList<>(); //构造一个初始容量 ...

  5. Spring Boot源码简析 @EnableTransactionManagement

    相关阅读 Spring Boot源码简析 事务管理 Spring Boot源码简析 @EnableAspectJAutoProxy Spring Boot源码简析 @EnableAsync Sprin ...

  6. ffmpeg实战教程(十三)iJKPlayer源码简析

    要使用封装优化ijk就必须先了解ffmpeg,然后看ijk对ffmpeg的C层封装! 这是我看ijk源码时候的笔记,比较散乱.不喜勿喷~ ijk源码简析: 1.ijkplayer_jni.c 封装的播 ...

  7. 【Android项目】本地FM收音机开发及源码简析

    [Android项目]本地FM收音机开发及源码简析 目录 1.概述 2.收音机的基本原理 3.收音机其他信息 RDS功能 4.Android开发FM收音机源码解析 5.App层如何设计本地FM应用 6 ...

  8. Log-Pilot 源码简析

    Log-Pilot 源码简析 简单介绍 源码简析 Pilot结构体 Piloter接口 main函数 Pilot.Run Pilot.New Pilot.watch Pilot.processEven ...

  9. Lottie动画框架入门及源码简析

    现在越来越多的APP中添加动画来提升用户体验,下面简单介绍下Airbnb开源的动画框架Lottie的使用 一.基本使用 首先添加依赖 compile 'com.airbnb.android:lotti ...

最新文章

  1. Atitit.研发管理---api版本号策略与版本控制
  2. 完美解决vue项目中弹出框滑动时,内部页面也跟着滑动问题
  3. shape的各种获取、更改以及设置方式辨析
  4. CST 使用注意事项【持续更新】
  5. JMF视频音频通信( 图+源码 )
  6. 省会城市房价地图,这9座新星城市正在悄然崛起
  7. 卡巴斯基终生免费使用方法
  8. Xen调度分析-RT
  9. aspen如何确定塔板数_Aspen Plus入门教程(3)-简捷法计算理论板数
  10. MAC jd-gui 安装
  11. SEO|解析关键词密度与分布
  12. 计算机能安装几个硬盘,一台电脑最多能接多少个硬盘?
  13. android+imei+为null,适合Android7.0以上(到9.0)系统,获取 关于手机--状态信息 (如:MAC,IMEI,IMSI,ICCID)...
  14. AppStore跳转链接
  15. 怎么制作公司网页教程【网站制作】
  16. Java 并发编程解析 | 如何正确理解Java领域中的多线程模型,主要用来解决什么问题?
  17. FXDD-点值获利计算
  18. 动态规划:高阶马尔科夫模型
  19. 【gitlab+jenkins+docker】第一节 基础环境介绍与准备
  20. 自学java怎么快速入门?

热门文章

  1. SQL--数据库的操作(DDL,DML,DQL)+使用命令查看当前数据库的存储位置(数据库版本查询)
  2. 为app添加动态gif背景
  3. 有没有大佬知道,有哪些可以在网页上自动填写账号密码并登录的方法?
  4. 如何关闭win7下的打开文件安全警告
  5. python摄像头拍照比对_如何使用Python控制摄像头拍照并发邮件?
  6. Program type already present问题解决
  7. 【GoDance搜索引擎】搜索引擎集群模块实现笔记
  8. 二分查找算法详解(经典二分和左右边界查找)
  9. Oracle服务器性能优化
  10. Python第六次学习例题---表、题:“三国演义”和“柯南系列41部合集”词云