目录
前言
查阅各种资料发现CMSIS-DAP的移植都是基于STM32F103系列,在此打算自己移植STM32H7的CMSIS-DAP。打开keil DAP官网,看CMSIS-DAP框图可以知道Cortex-M系列的MCU都可以运行CMSIS-DAP的代码。
收集各种资料后,拿起手上的STM32H743开始移植代码,移植SWD和USB部分,去掉对我多余的JTAG部分,UART部分暂时放着。
CubeMX
打开外部高速时钟
配置时钟,系统时钟400MHz,USB时钟48MHz
配置GPIO,时钟swd_clk、数据swd_io用于模拟SWD信号,LED灯显示状态,reset引脚我虽然配置的但没有使用,实际用的软件reset。
打开全速USB Device模式
ST提供USB库具体可以查阅UM1734用户手册 STM32Cube USB 设备库。
在这需要使用到USB DEVICE Costem HID,配置如下
描述符的CMSIS-DAP比较重要,keil会通过这个描述符来识别。
扩大堆栈,然后生成代码
DAP
移植CMSIS-DAP v1的代码。
右键项目,设置需要的头文件路径和.c代码路径
配置DAP_config.h
重点在GPIO寄存器部分,我用的PB7、PB8,如更换其他GPIO一定注意输入输出寄存器那部分的 temp ; //Modify according to your GPIO,具体改什么请查阅STM32H7用户手册GPIO部分。
#ifndef __DAP_CONFIG_H__
#define __DAP_CONFIG_H__
#define CPU_CLOCK SystemCoreClock ///< Specifies the CPU Clock in Hz
#define IO_PORT_WRITE_CYCLES 2 ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0
#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available
#define DAP_JTAG 0 ///< JTAG Mode: 0 = not available
#define DAP_JTAG_DEV_CNT 8 ///< Maximum number of JTAG devices on scan chain
#define DAP_DEFAULT_PORT 1 ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
#define DAP_DEFAULT_SWJ_CLOCK 10000000 ///< Default SWD/JTAG clock frequency in Hz.
/// Maximum Package Size for Command and Response data.
#define DAP_PACKET_SIZE 64 ///< USB: 64 = Full-Speed, 1024 = High-Speed.
/// Maximum Package Buffers for Command and Response data.
#define DAP_PACKET_COUNT 64 ///< Buffers: 64 = Full-Speed, 4 = High-Speed.
/// Indicate that UART Serial Wire Output (SWO) trace is available.
#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available
#define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz
/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available
#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n)
/// Debug Unit is connected to fixed Target Device.
#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
//**************************************************************************************************
/**
JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
---------------------------- | -------------------- | ---------------------------------------------
TCK: Test Clock | SWCLK: Clock | Output Push/Pull
TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
TDI: Test Data Input | | Output Push/Pull
TDO: Test Data Output | | Input
nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
DAP Hardware I/O Pin Access Functions
*/
#include "stm32h7xx.h"
#include "main.h"
// Configure DAP I/O pins ------------------------------
#define SWD_GPIO swd_io_GPIO_Port
#define CLK_GPIO swd_clk_GPIO_Port
#define PIN_SWCLK swd_clk_Pin
#define PIN_SWDIO swd_io_Pin
/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
- TDO to input mode.
*/
__STATIC_INLINE void PORT_JTAG_SETUP(void)
{
#if (DAP_JTAG != 0)
#endif
}
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
*/
__STATIC_INLINE void PORT_SWD_SETUP(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SWD_GPIO->BSRR = PIN_SWCLK | PIN_SWDIO;
GPIO_InitStruct.Pin = PIN_SWCLK | PIN_SWDIO;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SWD_GPIO, &GPIO_InitStruct);
}
/** Disable JTAG/SWD I/O Pins.
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/
__STATIC_INLINE void PORT_OFF(void)
{
HAL_GPIO_DeInit(SWD_GPIO,PIN_SWDIO);
HAL_GPIO_DeInit(CLK_GPIO, PIN_SWCLK);
}
// SWCLK/TCK I/O pin -------------------------------------
// Current status of the SWCLK/TCK DAP hardware I/O pin
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void)
{
return (CLK_GPIO->ODR & PIN_SWCLK) ? 1 : 0;
}
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void)
{
CLK_GPIO->BSRR = PIN_SWCLK;
}
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void)
{
CLK_GPIO->BSRR = PIN_SWCLK<<16U;
}
// SWDIO/TMS Pin I/O --------------------------------------
// Current status of the SWDIO/TMS DAP hardware I/O pin
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void)
{
return (SWD_GPIO->IDR & PIN_SWDIO) ? 1 : 0;
}
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)//1
{
SWD_GPIO->BSRR = PIN_SWDIO;
}
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void)//0
{
SWD_GPIO->BSRR = PIN_SWDIO<<16U;
}
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void)
{
return (SWD_GPIO->IDR & PIN_SWDIO) ? 1 : 0;
}
__STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit)
{
if(bit & 1)
SWD_GPIO->BSRR = PIN_SWDIO;
else
SWD_GPIO->BSRR = PIN_SWDIO<<16;
}
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void)
{
uint32_t temp;
temp = SWD_GPIO->MODER;
temp &= 0xFFFCFFFF; //Modify according to your GPIO
temp |= 0x00010000; //Modify according to your GPIO
SWD_GPIO->MODER = temp;
SWD_GPIO->BSRR = PIN_SWDIO<<16U;
}
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void)
{
uint32_t temp;
temp = SWD_GPIO->MODER;
temp &= 0xFFFCFFFF; //Modify according to your GPIO
SWD_GPIO->MODER = temp;
SWD_GPIO->BSRR = PIN_SWDIO<<16U;
}
// TDI Pin I/O ---------------------------------------------
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void)
{
#if (DAP_JTAG != 0)
#endif
return 0;
}
__STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit)
{
#if (DAP_JTAG != 0)
#endif
}
// TDO Pin I/O ---------------------------------------------
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void)
{
#if (DAP_JTAG != 0)
#endif
return 0;
}
// nTRST Pin I/O -------------------------------------------
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void)
{
return 0;
}
__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit)
{
}
// nRESET Pin I/O------------------------------------------
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
{
return 0;
}
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
}
//**************************************************************************************************
/** Connect LED: is active when the DAP hardware is connected to a debugger
Running LED: is active when program execution in target started
*/
static __inline void LED_CONNECTED_OUT(uint32_t bit)
{
if(bit & 0X01)
{
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
}
}
static __inline void LED_RUNNING_OUT(uint32_t bit)
{
if(bit & 0X01)
{
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
}
}
__STATIC_INLINE void DAP_SETUP(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
PORT_OFF();
}
__STATIC_INLINE uint32_t RESET_TARGET(void)
{
return (0); // change to '1' when a device reset sequence is implemented
}
#endif // __DAP_CONFIG_H__
USB
因为对USB驱动开发不是很熟,这部分调试花了一点时间,用到了一些USB调试软件对我很有帮助。
USB HID Demonstrator,这是ST官方例程对应的软件,对于USB HID不熟悉的一定要去看一下CustomHID——Standalone这个例程,再用抓包软件去抓一下数据。
USB Device Tree Viewer,查看USB设备和描述符比较方便。
Bus Hound,USB抓包必备。还可以可以Report,但是不知道为什么有时候会失灵。
HID调试工具,用来发送report。
编写usbd_custom_hid_if.c代码,
在H7上面一定要注意加上USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);去接收包,要不然只能响应因此OUT。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_custom_hid_if.c
* @version : v2.0_Cube
* @brief : USB Device Custom HID interface file.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_custom_hid_if.h"
/* USER CODE BEGIN INCLUDE */
#include "DAP.h"
#include "DAP_config.h"
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief Usb device.
* @{
*/
/** @addtogroup USBD_CUSTOM_HID
* @{
*/
/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions USBD_CUSTOM_HID_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_CUSTOM_HID_Private_Defines USBD_CUSTOM_HID_Private_Defines
* @brief Private defines.
* @{
*/
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/** @defgroup USBD_CUSTOM_HID_Private_Macros USBD_CUSTOM_HID_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_CUSTOM_HID_Private_Variables USBD_CUSTOM_HID_Private_Variables
* @brief Private variables.
* @{
*/
/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
/* USER CODE BEGIN 0 */
/* A minimal Report Desc with INPUT/OUTPUT/FEATURE report. Zach Lee */
0x06, 0x00, 0xFF, /* Usage Page (vendor defined) ($FF00) global */
0x09, 0x01, /* Usage (vendor defined) ($01) local */
0xA1, 0x01, /* Collection (Application) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0xFF, /* LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8bit) */
// Input Report
0x95, DAP_PACKET_SIZE, /* Report Length (64 REPORT_SIZE) */
0x09, 0x01, /* USAGE (Vendor Usage 1) */
0x81, 0x02, /* Input(data,var,absolute) */
// Output Report
0x95, DAP_PACKET_SIZE, /* Report Length (64 REPORT_SIZE) */
0x09, 0x01, /* USAGE (Vendor Usage 1) */
0x91, 0x02, /* Output(data,var,absolute) */
// Feature Report
0x95, DAP_PACKET_SIZE, /* Report Length (64 REPORT_SIZE) */
0x09, 0x01, /* USAGE (Vendor Usage 1) */
0xB1, 0x02, /* Feature(data,var,absolute) */
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
};
/* USER CODE BEGIN PRIVATE_VARIABLES */
volatile uint32_t RequestPauseProcessing;
extern volatile uint8_t DAP_TransferAbort;
extern volatile uint32_t RequestPendingCount;
static volatile uint32_t RequestIndexPending;
extern uint8_t USB_DAP_Requests[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
/* USER CODE END PRIVATE_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes USBD_CUSTOM_HID_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t CUSTOM_HID_Init_FS(void);
static int8_t CUSTOM_HID_DeInit_FS(void);
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state);
/**
* @}
*/
USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
{
CUSTOM_HID_ReportDesc_FS,
CUSTOM_HID_Init_FS,
CUSTOM_HID_DeInit_FS,
CUSTOM_HID_OutEvent_FS
};
/** @defgroup USBD_CUSTOM_HID_Private_Functions USBD_CUSTOM_HID_Private_Functions
* @brief Private functions.
* @{
*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the CUSTOM HID media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CUSTOM_HID_Init_FS(void)
{
/* USER CODE BEGIN 4 */
RequestIndexPending = 0;
RequestPauseProcessing = 0;
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief DeInitializes the CUSTOM HID media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CUSTOM_HID_DeInit_FS(void)
{
/* USER CODE BEGIN 5 */
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Manage the CUSTOM HID class events
* @param event_idx: Event index
* @param state: Event state
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
/* USER CODE BEGIN 6 */
// printf("out event\r\n");
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hhid->Report_buf[0] == ID_DAP_TransferAbort) {
DAP_TransferAbort = 1U;
RequestPauseProcessing = 0;
} else {
if (RequestPendingCount < DAP_PACKET_COUNT) {
memcpy(USB_DAP_Requests[RequestIndexPending++], hhid->Report_buf, DAP_PACKET_SIZE);
if (RequestIndexPending >= DAP_PACKET_COUNT)
RequestIndexPending = 0;
if (hhid->Report_buf[0] == ID_DAP_QueueCommands)
RequestPauseProcessing = 1;
else
RequestPauseProcessing = 0;
RequestPendingCount++;
} else if (RequestPauseProcessing) {
// This will cause deadlock. Host is not honoring packet count limits.
// Release pause.
RequestPauseProcessing = 0;
}
}
USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
/* USER CODE BEGIN 7 */
/* USER CODE END 7 */
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
修改 usbd_customhid.h,修改CUSTOM_HID_EPIN_SIZE和CUSTOM_HID_EPOUT_SIZE为0x40(64),这两个宏代表输入输出report的大小,默认是2,太小了,导致速度很慢。这部分使用CubeMX重新生成代码会还原,注意备份一下。
Main
除了在线烧录还成功测试了离线烧录,在swd_test() 。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "DAP.h"
#include "DAP_config.h"
#include "usbd_custom_hid_if.h"
#include "SWD_host.h"
#include "SWD_flash.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#include "../../algo/STM32F10x_128.c"
uint32_t Flash_Page_Size = 1024;
uint32_t Flash_Start_Addr = 0x08000000;
uint8_t buff[1024] = {0};
uint8_t test[7] = {0,1,2,3,4,5,6};
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
static uint32_t CommonIndex;
static uint32_t ResponseIndexSend;
static uint32_t ResponsePendingCount;
volatile uint32_t RequestPendingCount;
extern USBD_HandleTypeDef hUsbDeviceFS;
extern volatile uint32_t RequestPauseProcessing;
uint8_t USB_DAP_Requests[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
uint8_t USB_DAP_Responses[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
static void Send_USB_DAP_Response(void);
void swd_test();
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t skip_sending_response;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
CommonIndex = 0;
ResponseIndexSend = 0;
ResponsePendingCount = 0;
RequestPendingCount = 0;
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
printf("begin\r\n");
// swd_test();
// while(1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
while ((RequestPendingCount > 0) && (ResponsePendingCount < DAP_PACKET_COUNT))
{
if (USB_DAP_Requests[CommonIndex][0] == ID_DAP_QueueCommands)
{
// Pause request processing until all queue commands are received.
if (RequestPauseProcessing)
break;
USB_DAP_Requests[CommonIndex][0] = ID_DAP_ExecuteCommands;
// Avoid sending usb response during processing queued commands.
skip_sending_response = 1;
}
else
{
skip_sending_response = 0;
}
DAP_ExecuteCommand(USB_DAP_Requests[CommonIndex], USB_DAP_Responses[CommonIndex]);
RequestPendingCount--;
ResponsePendingCount++;
CommonIndex++;
if (CommonIndex >= DAP_PACKET_COUNT) {
CommonIndex = 0;
}
if (skip_sending_response == 0)
Send_USB_DAP_Response();
}
if (ResponsePendingCount > 0)
{
Send_USB_DAP_Response();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 8;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED_G_Pin|swd_rst_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : LED_G_Pin */
GPIO_InitStruct.Pin = LED_G_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_G_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : swd_rst_Pin */
GPIO_InitStruct.Pin = swd_rst_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(swd_rst_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : swd_clk_Pin swd_io_Pin */
GPIO_InitStruct.Pin = swd_clk_Pin|swd_io_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
void Send_USB_DAP_Response(void) {
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hhid->state == CUSTOM_HID_IDLE) {
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, USB_DAP_Responses[ResponseIndexSend], DAP_PACKET_SIZE);
ResponseIndexSend++;
if (ResponseIndexSend >= DAP_PACKET_COUNT) {
ResponseIndexSend = 0;
}
ResponsePendingCount--;
}
}
//swd offline test code
void swd_test()
{
error_t error;
if( (error = target_flash_init(Flash_Start_Addr)) != 0)
{
printf("target_flash_init error %d\r\n",error);
return ;
}
printf("target_flash_init success!!!!!!!!!!!!!!\r\n");
for(uint32_t addr = 0; addr < sizeof(test); addr += 1024)
{
if( (error = target_flash_erase_sector(0x08000000+addr)) != 0)
{
printf("target_flash_erase_sector error %d\r\n",error);
return ;
}
}
printf("target_flash_erase_sector !!!!!!!!!!!!!!\r\n");
for(uint32_t addr = 0; addr < sizeof(test); addr += 1024)
{
swd_read_memory(0x08000000 + addr, buff, 1024);
for(uint32_t i = 0; i < 1024; i++) printf("%02X ", buff[i]);
printf("\r\n\r\n\r\n");
}
for(uint32_t addr = 0; addr < sizeof(test); addr += 1024)
{
target_flash_program_page(0x08000000+addr, &test[addr], 1024);
}
for(uint32_t addr = 0; addr < sizeof(test); addr += 1024)
{
swd_read_memory(0x08000000 + addr, buff, 1024);
for(uint32_t i = 0; i < 1024; i++) printf("%02X ", buff[i]);
printf("\r\n\r\n\r\n");
}
swd_set_target_state_hw(RUN);
}
/* 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 */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
结果
在线烧录
离线烧录