开源SWD脱机烧录器-第二章 SWD协议移植
/********************2020.03.02更新********************/
感谢博友的提醒我忘记上传Qt源码了,这就补上
https://gitee.com/airtech/offline_Qt
/**********************************************2020.01.20*****************************************/
开源地址:https://gitee.com/airtech/offline_burner
/**********************************************2019.12.31******************************************/
部分代码参考了https://github.com/wuxx/nanoDAP
将上一章提到文件加入工程中“DPA.c/error.c/SW_DP.c/target_flash.c/swd_host.c/flash_blob.c”
这是我的,SWD_FLASH.c对应的是target_flash.c
先打开#include "DAP_config.h"配置文件,在这里面配置SWD的引脚和相关参数
按照下面配置,直接复制就好了
SWD引脚IO定义:
SWD引脚IO操作定义
/***********************DAP_config.h end**********************/
SW_DP.C文件移植:
最主要的改动都在SW-DP和SWD_host两个文件。
奇偶校验数组:
将SWJ_Sequence的内容改成:
将SWD_Transfer_Buff内容改成:
uint8_t SWD_Transfer_Buff(uint32_t request, uint32_t *data)
{uint8_t ack=0; uint32_t bit; uint32_t val; uint32_t parity=0U; uint8_t req_buf=0U;uint8_t Start[8]; uint32_t n; uint8_t vall[5];uint8_t val_TX[4]={0xFF,0xFF,0xFF,0xFF};uint32_t val_buf;/* Packet Request */ SPI_Switch(1);parity = 0U;Start[0]=1U;bit=request >> 0;Start[1]=bit&0x01;parity += bit;bit= request >> 1;Start[2]=bit&0x01;parity += bit;bit= request >> 2;Start[3]=bit&0x01;parity += bit;bit= request >> 3;Start[4]=bit&0x01;parity += bit;Start[5]=parity&0x01;Start[6]=0U;Start[7]=1U;req_buf=(Start[0]<<0) | (Start[1]<<1) | (Start[2]<<2) | (Start[3]<<3) | (Start[4]<<4) | (Start[5]<<5) | (Start[6]<<6) | (Start[7]<<7); SPI1_ReadWriteByte(req_buf); SPI_Switch(0);/* Turnaround */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) {SPI_Switch(1); /* Read data */ val = 0U; parity = 0U;SPI_TXRX(val_TX,vall,4);val=vall[0]<<0 | vall[1]<<8 | vall[2]<<16 | vall[3]<<24;val_buf^=val_buf>>16;val_buf^=val_buf>>8;parity=ParityTable256[val_buf & 0xff]&0x01;SPI_Switch(0);SW_READ_BIT(bit);
// if ((parity ^ bit) & 1U)
// {
// ack = DAP_TRANSFER_ERROR;
// } if (data) { *data = (val); } /* Turnaround */ val = 0U; parity = 0U; for (n = DAP_Data.swd_conf.turnaround; n; n--) { SW_CLOCK_CYCLE(); } } else { /* Turnaround */ for (n = DAP_Data.swd_conf.turnaround; n; n--) { SW_CLOCK_CYCLE(); } SPI_Switch(1); /* Write data */ val = *data; parity = 0U;vall[0]=val&0xFF;vall[1]=val>>8&0xFF;vall[2]=val>>16&0xFF;vall[3]=val>>24&0xFF;val_buf=vall[0]<<0 | vall[1]<<8 | vall[2]<<16 | vall[3]<<24;val_buf^=val_buf>>16;val_buf^=val_buf>>8;parity=ParityTable256[val_buf & 0xff];SPI_TX4(vall);/* Write WDATA[0:31] */SPI_Switch(0); 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 ack; } if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { SPI_Switch(0);/* 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(); } if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { printf("(DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))\r\n");PIN_SWDIO_OUT(0U); for (n = 32U+1U; n; n--) { SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ } } PIN_SWDIO_OUT(1U); return ack; } /* Protocol error */ for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { SW_CLOCK_CYCLE(); /* Back off data phase */ } PIN_SWDIO_OUT(1U); return ack;
}
剩下的几个函数改成:
/************************SW_DP END************************/
移植swd_host:
将JTAG2SWD函数内容改成
static uint8_t JTAG2SWD()
{uint32_t tmp = 0;uint8_t LineRst[7]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};uint8_t swd_switch1[2]={0x9E,0xE7};uint8_t swd_switch2[2]={0x6D,0xB7};SPI_TX7(LineRst);SPI_TX2(swd_switch1);SPI_TX7(LineRst);SPI_TX2(swd_switch2);SPI_TX7(LineRst);if (!swd_read_idcode(&tmp)) {printf("Read IDCODE Fault 0x%.4X\r\n",tmp);return 0;}
// printf("IDCODE : 0x%.4X\r\n",tmp);return 1;
}
软件复位:
//-----Soft reset + Hard reset-------------------------------------------------
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR#define RST_CLOCK_CYCLE() \PIN_SWCLK_CLR(); \PIN_DELAY(); \PIN_SWCLK_SET(); \PIN_DELAY()#define RST_WRITE_BIT(bit) \PIN_SWDIO_OUT(bit); \PIN_SWCLK_CLR(); \PIN_DELAY(); \PIN_SWCLK_SET(); \PIN_DELAY()#define RST_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)
#define PIN_DELAY() PIN_DELAY_FAST()uint8_t RST_Transfer(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; \RST_WRITE_BIT(1U); /* Start Bit */ \bit = request >> 0; \RST_WRITE_BIT(bit); /* APnDP Bit */ \parity += bit; \bit = request >> 1; \RST_WRITE_BIT(bit); /* RnW Bit */ \parity += bit; \bit = request >> 2; \RST_WRITE_BIT(bit); /* A2 Bit */ \parity += bit; \bit = request >> 3; \RST_WRITE_BIT(bit); /* A3 Bit */ \parity += bit; \RST_WRITE_BIT(parity); /* Parity Bit */ \RST_WRITE_BIT(0U); /* Stop Bit */ \RST_WRITE_BIT(1U); /* Park Bit */ \\/* Turnaround */ \PIN_SWDIO_OUT_DISABLE(); \for (n = DAP_Data.swd_conf.turnaround; n; n--) { \RST_CLOCK_CYCLE(); \} \\/* Acknowledge response */ \RST_READ_BIT(bit); \ack = bit << 0; \RST_READ_BIT(bit); \ack |= bit << 1; \RST_READ_BIT(bit); \ack |= bit << 2; \\/* Data transfer */ \/* Turnaround */ \for (n = DAP_Data.swd_conf.turnaround; n; n--) { \RST_CLOCK_CYCLE(); \} \\/* Write data */ \val = data; \parity = 0U; \for (n = 32U; n; n--) { \RST_WRITE_BIT(val); /* Write WDATA[0:31] */ \parity += val; \val >>= 1; \} \RST_WRITE_BIT(parity); /* Write Parity Bit */ \\PIN_SWDIO_OUT(1U); \return ((uint8_t)ack); \
}void vResetTarget(uint8_t bit)
{uint32_t i;//soft-reset for Cortex-MRST_Transfer(0x00000CC5, 0xE000ED0C); //set AIRCR addressfor (i=0; i<100; i++);RST_Transfer(0x00000CDD, 0x05FA0007); //set RESET datafor (i=0; i<100; i++);RST_Transfer(0x00000CC5, 0xE000ED0C); //repeatfor (i=0; i<100; i++);RST_Transfer(0x00000CDD, 0x05FA0007);if (bit & 1) PIN_nRESET_HIGH();else PIN_nRESET_LOW();
}
/* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}
SWD的部分移植完成了。
SPI配置:
SWD_SPI操作函数
u8 SPI1_ReadWriteByte(u8 TxData)
{ u16 retry=0; while((SPI1->SR&1<<1)==0) //µÈ´ý·¢ËÍÇø¿Õ {retry++;if(retry>=0XFFFE)return 0; //³¬Ê±Í˳ö} SPI1->DR=TxData; //·¢ËÍÒ»¸öbyte retry=0;while((SPI1->SR&1<<0)==0) //µÈ´ý½ÓÊÕÍêÒ»¸öbyte {retry++;if(retry>=0XFFFE)return 0; //³¬Ê±Í˳ö} return SPI1->DR; //·µ»ØÊÕµ½µÄÊý¾Ý
}uint8_t SPI_TXRX(uint8_t *TXBuff,uint8_t *RXBuff,uint8_t cnt)
{uint8_t cnt_buff;for(cnt_buff=0;cnt_buff<cnt;cnt_buff++){RXBuff[cnt_buff]=SPI1_ReadWriteByte(TXBuff[cnt_buff]);}return 1;
}uint8_t SPI_TX(uint8_t *TXBuff,uint8_t cnt)
{uint8_t cnt_buff;for(cnt_buff=0;cnt_buff<cnt;cnt_buff++){SPI1_ReadWriteByte(TXBuff[cnt_buff]);}return 1;
}uint8_t SPI_TX7(uint8_t *TXBuff)
{SPI1_ReadWriteByte(TXBuff[0]);SPI1_ReadWriteByte(TXBuff[1]);SPI1_ReadWriteByte(TXBuff[2]);SPI1_ReadWriteByte(TXBuff[3]);SPI1_ReadWriteByte(TXBuff[4]);SPI1_ReadWriteByte(TXBuff[5]);SPI1_ReadWriteByte(TXBuff[6]);return 1;
}uint8_t SPI_TX4(uint8_t *TXBuff)
{SPI1_ReadWriteByte(TXBuff[0]);SPI1_ReadWriteByte(TXBuff[1]);SPI1_ReadWriteByte(TXBuff[2]);SPI1_ReadWriteByte(TXBuff[3]);return 1;
}uint8_t SPI_TX2(uint8_t *TXBuff)
{SPI1_ReadWriteByte(TXBuff[0]);SPI1_ReadWriteByte(TXBuff[1]);return 1;
}
SPI初始化和SPI/模拟IO切换
/*** @brief SPI1 Initialization Function* @param None* @retval None*/static void DeInit_SPI(void)
{SPI1->CR1 |=0<<6;RCC->APB2ENR |=0<<12;RCC->APB2ENR |=0;GPIOB->CRL &=0xF0000FFF;GPIOB->CRL |=0x03743000;GPIOB->BRR=GPIO_PIN_3;GPIOB->BSRR=GPIO_PIN_5;
}static void SPI_ON(void)
{RCC->APB2ENR |=1<<12;RCC->APB2ENR |=1<<0;GPIOB->CRL &=0xF0000FFF;//GPIO INITGPIOB->CRL |=0x03F4B000;//GPIO INITSPI1->CR1 |=1<<6;//EN SPI
}void SPI_Switch(uint8_t ONOFF)
{if(ONOFF==1) SPI_ON();else DeInit_SPI();
}static void MX_SPI1_Init(void)
{/* USER CODE BEGIN SPI1_Init 0 */RCC->APB2ENR |=1<<12;//SPI CK ENRCC->APB2ENR |=1<<3;//GPIO CK ENGPIOB->CRL &=0xF0000FFF;//GPIO INITGPIOB->CRL |=0x03F4B000;//GPIO INITSPI1->CR1 |=0<<10;//DOUBULESPI1->CR1 |=1<<9;SPI1->CR1 |=1<<8;SPI1->CR1 |=1<<7;//LSBSPI1->CR1 |=0<<11;//8BITSPI1->CR1 |=1<<2;//HOSTSPI1->CR1 |=0<<1;//CPOL LOWSPI1->CR1 |=0<<0;//CPHA 1EDGESPI1->CR1 |=2<<3;//F/8SPI1->CR1 |=1<<6;//EN SPI/* USER CODE END SPI1_Init 0 */
}
到此移植基本上完成了,再解决一下编译的error就OK了
注意我的硬件是SPI中MISO和MOSI是接在一起的,所以MOSI引脚要设置为OD,MISO设置为input。切换成普通GPIO时也要这样配置。
开源SWD脱机烧录器-第二章 SWD协议移植相关推荐
- 开源SWD脱机烧录器-第一章 软硬件配置及其初始化
/********************2020.03.02更新********************/ 感谢博友的提醒我忘记上传Qt源码了,这就补上 https://gitee.com/airt ...
- 开源SWD脱机烧录器-第三章 基于QT的上位机
/********************2020.03.02更新********************/ 感谢博友的提醒我忘记上传Qt源码了,这就补上 https://gitee.com/airt ...
- 开源SWD脱机烧录器-前言
/********************2020.03.02更新********************/ 感谢博友的提醒我忘记上传Qt源码了,这就补上 https://gitee.com/airt ...
- swd脱机烧录器及上位机源码_通用上位机框架HwLib.Automation(C#)
概述 现在的工业自动化领域,虽然组态软件因简单易用.价格合理而被广泛部署到各行各业的控制系统上.但对于一部分应用场景来说,自己开发上位机应用程序依然占有不小的市场,诸如: 1.标准化设备厂商,大量的软 ...
- H7-TOOL脱机烧录器支持1拖4,支持新唐,GD32,MM32,AT32,APM32,CX32,STM32,STM8,i.MX RT,W7500,外置Flash等2020-10-27
大家在使用中,有什么建议,欢迎反馈. 脱机烧录视频效果展示: http://v.qq.com/x/page/p30628h2ou7.html 多款STM8+STM32产品混合烧录展示: http:// ...
- STM32脱机烧录器源文件、离线烧录器 制作资料 源文件
STM32脱机烧录器源文件.离线烧录器 制作资料 源文件 STM32 脱机烧录器制作资料,SWD协议. 已制作验证,可以脱机烧录STM32F0 F1 F2 F4 L0系列, 不提供制作. 资料内容: ...
- STM32 STM8 GD32 脱机烧录器 ,
stm32 SWD模式脱机烧录器,有需要的看看 https://download.csdn.net/download/li880wert/11119094 用的STM32F103C8T6 或STLI ...
- 产品量产 要用到脱机烧录器
上面两种(ISP SWD)都是要连着电脑的,适用于开发,在量产的时候要用到脱机烧录器,把程序放到烧录器里,然后直接拿着烧录器给一个个芯片下载程序. 长这样,里面可以放几百个程序,按中间的蓝色按钮烧录.
- K202 及 K216 款脱机烧录器 固件升级方法 支持STM8 STM32 Nordic 芯片 EFM8 EFM32 C8051F 等芯片
K202.K204 及 K216 款脱机烧录器 固件升级方法 支持STM8 STM32 Nordic 芯片 EFM8 EFM32 C8051F 等芯片 需要升级固件, 固件为如下(或者由我们提供最 ...
最新文章
- python爬取疫情信息html.xpath p标签_python xpath 如何过滤div中的script和style标签
- 好雨云帮近期问答集锦(1.16~2.5)
- *62.分页和分段的区别
- 举例说明信息熵、互信息的计算过程
- Java 字符串性能对比
- java面试总结(一)-----如何准备Java初级和高级的技术面试
- linux spf13 vim安装,Linux 下安装 spf13-VIM
- Java业务代理模式~
- 矩池云上matplotlib显示中文乱码
- 中国捆矛行业市场供需与战略研究报告
- android 球形进度,android仿360手机卫士的自定义波浪球形进度View 滚动痕迹
- 数据结构之排序算法Java实现(8)—— 线性排序之计数排序算法
- VSA Cluster中小企业无SAN环境解决方案
- 电脑 Google浏览器 截长屏 无任何辅助软件
- 树莓派之Debian游戏(部分)
- 熊猫的python小课账号_校长,我要上车——python模拟登录熊猫TV
- cs透视源码c语言,CS--GO透视自瞄C++源码 CSGO C++源代码 参考学习!!!(CSGO C++ source code) - 下载 - 搜珍网...
- math.floor javascript
- 什么是MTTF、MTBF、MTRF
- 基于pam实现的批量执行命令工具-Cyberark
热门文章
- Qt - 换肤功能实现
- 电脑怎么找到tomcat端口_查看tomcat端口号(怎么看tomcat的端口号)
- Vue项目首页-热销推荐组件开发(7-6)
- CDA Level 1 数据分析师:6.2 指标的应用与设计
- 交换机分布缓存_述说数据中心交换机的重要性能指标——缓存
- 【路径规划】viroion地图无人机路径规划matlab代码
- 《支付系统-3交易系统》
- 保加利亚 乱码_保加利亚PHP的回顾-游戏开始!
- mdx格式mysql_Schema Workbench 开发mdx和模式文件
- 2034——人见人爱A-B