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) // PB2SWD通信时序分析所有时序的实现,由CPU操作IO口完成. 通信速率在一个通信时钟周期会调用二次SWD_Delay()即$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. 双向引脚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 data for(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数据. ...