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数据. ...

November 3, 2019 · 2 min · jiezi

修改LGT8F328P的Arduino-BOOTLOADER支持波特率115200bps

从Larduino_HSP取得的LGT8F328P的bootloader通过串口与主机通信,其波特率为57600bps.修改更新的波特率可以提高写入速度,节省时间.如果直接在Makefile修改为 115200bps的话 BAUD_RATE_CMD = -DBAUD_RATE=115200编译会有波特率偏移超过2%的提示,可能会影响通信. 警告: #warning BAUD_RATE error greater than -2% [-Wcpp]这里主要修改两个地方,以更好的工作在115200bps. 1. 启用倍速功能倍速工作模式 通过设定 UCSRA 寄存器的 U2X 位可以是传输速率加倍,该位只在异步工作模式下有效,同步工作模式下置该位为“0”。设置该位将会把波特率分频器的分频值减半,有效地加倍异步通信的传输速率。在这种情况下,接收器只使用一半的采样数来对数据进行采样及时钟恢复,因此需要更精准的波特率设置和系统时钟。发送器则没有变化。参考手册,启用倍速功能,此时波特率计算公式为 工作模式波特率计算公式UBRR 值计算公式异步倍速模式$${\rm BAUD} = \frac{\large f_{\rm sys}}{\quad 8({\rm UBRR}+1)\quad }$$$${\rm UBRR} = \frac{\large f_{\rm sys}}{\quad 8{\rm BAUD}\quad } - 1$$当系统时钟为16000000,波特率取115200时,依公式$${\rm UBRR} = \displaystyle \frac{16000000}{8*115200} - 1 \approx 16.36$$UBRR将被赋值为0x10.此时实际的波特率约为$${\rm BAUD} = \displaystyle \frac{16000000}{\quad 8(16+1)\quad }\approx 117647$$ 偏差$$\frac{115200-117647}{115200}\approx -2.1\%$$ 在optiboot.c中修改代码: int main(void) {... UART_SRA = _BV(U2X0); //Double speed mode USART0 UART_SRL = (uint8_t)( F_CPU / (BAUD_RATE * 8L) - 1 );...}2. 调整系统时钟频率内部 RC 振荡器校准 LGT8FX8P 内部包含两个可校准 RC 振荡器,经过校准后,均可达到±1%以内的精度。其中 32MHz RC 默认用于系统工作时钟。LGT8FX8P 出产前,内部 32MHz HFRC 和 32KHz LFRC 都进行了校准,并把校准值写入系统配置信息区域。系统上电过程中,这些校准值将会被读入到内部寄存器中,通过寄存器实现对 RC 频率的重新校准。bootloader的系统时钟源使用的是内部 32MHz HFRC,并通过设置32MHz HFRC 振荡器校准寄存器- RCMCAL,达到±1%以内的精度.为使串口通信速率更接近115200bps,这时我们通过调整系统时钟来调整波特率.依前面公式,输出标准115200bps时,系统时钟最佳值为:$$\large f_{\rm sys} = {\rm BAUD}*{8({\rm UBRR}+1)}=115200*8(16+1)=15667200$$通过修改寄存器CLKPR的CKOEN0位,在PB0上检测系统时钟频率.以下为实测的经验数据: ...

November 2, 2019 · 1 min · jiezi

操作系统学习笔记(1)

bootloader 部分笔记bootloader 比较枯燥,主要是对各个寄存器进行设置,然后进行 BIOS 的 int10H 调用。需要用到一些汇编的知识,这里简要记录一些要点。BIOS int10H第十七个中断向量(interrupt vector),通常在实模式用于设置显示服务。需要配合 AH 一起使用,指定其子函数。清屏功能AH = 06H,向上滚动窗口AL = 00H,这时开启清屏功能BH 指定颜色属性,其余寄存器可暂时忽略(07即为黑底白字)设置 focusAH = 02HBH 为页码DH 为行数DL 为列数显示字符串AH = 13HAL 为写入模式BH 为页码BL 为颜色CX 存放字符串长度DH 为游标坐标行号DL 为游标坐标列号ES:BP 需要设置为字符串的偏移地址汇编要点org 指令,设置程序的起始段,避免再需要的地方手动就设置 0x7c00(主要影响绝对地址寻址指令)。最简单的显示字符串程序共用了代码断和数据段/extra 段,因此数据段放到了最后。org 0x7c00 ; set origin as 0x7c00mov ax, csmov es, ax ; es is equal to cs in this case; using int10h ah=06, al = 0 to clear screenmov ax, 0600hmov bx, 0700h; black background and white colormov cx, 0000hmov dx, 0xffffint 10h; using int10h, ah = 02h to set focusmov ax, 0200hmov bx, 0000hmov dx, 0000hint 10h; show stringmov ax, 1301h; AL = 01 indicates that after display string, the cursor will be the endmov bx, 0007hmov dx, 0000hmov cx, 10; length of stringmov bp, DisplayStringint 10hjmp $DisplayString: db “Hello Boot"times 510 - ($ - $$) db 0db 0x55, 0xaa ...

April 9, 2019 · 1 min · jiezi