开源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-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<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 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时也要这样配置。

  • 9
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 32
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值