/********************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-M
RST_Transfer(0x00000CC5, 0xE000ED0C); //set AIRCR address
for (i=0; i<100; i++);
RST_Transfer(0x00000CDD, 0x05FA0007); //set RESET data
for (i=0; i<100; i++);
RST_Transfer(0x00000CC5, 0xE000ED0C); //repeat
for (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
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 INIT
GPIOB->CRL |=0x03F4B000;//GPIO INIT
SPI1->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 EN
RCC->APB2ENR |=1<<3;//GPIO CK EN
GPIOB->CRL &=0xF0000FFF;//GPIO INIT
GPIOB->CRL |=0x03F4B000;//GPIO INIT
SPI1->CR1 |=0<<10;//DOUBULE
SPI1->CR1 |=1<<9;
SPI1->CR1 |=1<<8;
SPI1->CR1 |=1<<7;//LSB
SPI1->CR1 |=0<<11;//8BIT
SPI1->CR1 |=1<<2;//HOST
SPI1->CR1 |=0<<1;//CPOL LOW
SPI1->CR1 |=0<<0;//CPHA 1EDGE
SPI1->CR1 |=2<<3;//F/8
SPI1->CR1 |=1<<6;//EN SPI
/* USER CODE END SPI1_Init 0 */
}
到此移植基本上完成了,再解决一下编译的error就OK了
注意我的硬件是SPI中MISO和MOSI是接在一起的,所以MOSI引脚要设置为OD,MISO设置为input。切换成普通GPIO时也要这样配置。