你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【源代码】STM32F103C8T6最小板搞定CMSIS-DAP和SWO功能  

[复制链接]
radio2radio 发布时间:2018-5-31 15:47
阅读主题, 点击返回1楼
1 收藏 45 评论418 发布时间:2018-5-31 15:47
418个回答
ljlt 回答时间:2020-12-7 10:04:09
感谢分享,不错。
冬天ア之釜 回答时间:2021-1-8 14:10:55
看起来真的很不错
huawuqiu 回答时间:2021-1-11 17:04:57
感谢LZ分享~~~
ricklou 回答时间:2021-1-25 10:50:25
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduino ide),stm32好像有联络信号pa0和pa1,希望做一个,让复位时给一个低电平复位信号。1 n" S' }0 \, y& u
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
/ \; ]. F3 }; ^5 r$ R! {除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

) L2 a0 }' w: ]2 y: Y3 e. R  v我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。* S5 F0 q) z+ e) Q/ _5 Y8 H

& h& d% p  N* P. Z5 m软件复位是另外一种情况,需要向目标IC发送复位“密码”,Cortex的IC有这样的密码。 这就不需要连接nRESET线了。
ricklou 回答时间:2021-1-27 23:00:25
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号
radio2radio 回答时间:2021-1-28 18:01:27
ricklou 发表于 2021-1-27 23:00& t1 O  a5 b/ p6 A; I& n* F
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

) d6 d4 U1 l' u- ^nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。) W  w$ I2 R- ?7 ~1 h; W$ b+ y: {
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。  E. g) `  t& P5 p' i8 I

, W3 D' ?) ]% P8 X: X" m9 m你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 " T# y$ q1 E/ p3 a9 C
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
3 f/ t1 x2 S7 I& b  j* w, W7 t) B& L( i' x! G; P4 i1 \9 x
$ U5 |! V+ V$ Y& z$ s0 q* ^' K3 Y
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
7 _7 _: A# ^+ w; b3 z
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap 8 s: z! X4 ^" L; g; }) a
起点VS 回答时间:2022-8-12 09:23:24
正需要,这是好东西
KEVIN.Z 回答时间:2023-9-7 22:41:22
我也自己用ST官方标准库STM32_USB-FS-Device_Lib_V4.1.0移植了DAP V2.11版本的,即CMSIS 5.9.0里带的DAP,芯片型号用的STM32F103C8T6核心小板子,实际上我还有一块板子装上了APM32F103CBT6的,程序能通用,没跑RTX系统,轮询执行8 K) C/ i. b" O$ I! f. c! p/ x5 E
/**
; b5 n% e0 M/ j% _0 I  ******************************************************************************- K9 x/ L  c6 t$ L, W/ d
  * @file    usb_endp.c6 {6 o  M: i  O" S
  * @author  MCD Application Team
' y: Y+ v/ [; c+ {1 z9 s2 J6 \  * @version V4.1.0
; I+ ^0 B* _* L$ P7 s. F5 Z' p' Q  * @date    26-May-2017
/ X* @+ o8 r: ?7 t: A  * @brief   Endpoint routines
. L* O9 B  }$ v: u( a# ~% c0 g  ******************************************************************************
. C3 v# P  ^- B0 P  * @attention# w, j. |3 H. V* h! u2 A. c
  *
( o- k0 ?6 T8 J( R* ^; O  x  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>$ W: t7 U, ?% {3 R- c3 _2 i, O
  *9 O4 |1 {, \) Q
  * Redistribution and use in source and binary forms, with or without modification,
4 n2 E' h/ o) i  F/ g2 D/ M# d  * are permitted provided that the following conditions are met:3 I! P: H- N8 Y( D  D
  *   1. Redistributions of source code must retain the above copyright notice,
; O3 U: x- s7 Y1 c  *      this list of conditions and the following disclaimer.& L: Y, N% @5 H$ e) q7 t
  *   2. Redistributions in binary form must reproduce the above copyright notice,
( y8 B9 n  k) T# W0 T0 ?3 h2 X: @  *      this list of conditions and the following disclaimer in the documentation2 o+ j' l4 c0 r1 e
  *      and/or other materials provided with the distribution.% G/ F8 s: I# |: K7 H2 d$ r8 \& A
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
9 ?1 c6 B9 P/ n0 `* h  *      may be used to endorse or promote products derived from this software4 Q6 h0 t# T8 l: `. [
  *      without specific prior written permission.7 c4 }. H6 h7 Q* N5 M" Y
  *
% Q! o* t$ D/ N3 }, Q8 F3 E  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
, Z. d( c- C: B6 o2 y  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
$ b4 ^* I/ V" r6 Q* h0 `  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE4 d" q! g/ G. X$ e4 g7 e
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ n( V* p1 x7 E  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL1 N, K  i, c/ M6 \( \
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  _6 k' l9 A7 Y  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER) O8 m# ?& }3 S! Q& E
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5 e* l0 _, W* @2 x/ h0 Q6 X  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
$ w  a* I4 q% C) E, `; p  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; R/ R4 i! \: Z8 B7 {8 _  *2 w/ t, F: @4 D% ?# [5 a
  ******************************************************************************- }" M2 [  _: C/ p5 q. A$ l; e
  */8 F3 ]0 J- G8 z  [/ d  d
7 g/ g6 ]( y" ~3 e/ N  s
4 g* Q' c7 U4 z9 b- o+ {0 p
/* Includes ------------------------------------------------------------------*/+ z+ C  b# b" u5 a* C
#include "hw_config.h"0 G; V% `* o$ C7 o/ X3 M; I
#include "usb_lib.h"
7 |3 \& o# d  L7 u#include "usb_istr.h"
  ~5 ]" ~# O# x: h4 ]8 b' f$ H8 Q" m( D- ^#include "stepper.h"" H9 K* w* f2 g, g/ E+ r; X$ R
#include "string.h"5 Q. U' W7 T6 z3 y
, ]7 X' U* I! j  w0 ~
#include "DAP_config.h"
  I( J3 R' n9 }#include "DAP.h"
4 o. P8 N4 B% Y2 o8 Z7 ?! S  J& w) a6 A7 J( ?( j& ~1 E6 ?4 s" Z
' m5 {  q& t$ X# ]5 }8 S3 n
/* Private typedef -----------------------------------------------------------*/
  `+ L* M! k8 v1 S% y4 l8 y/* Private define ------------------------------------------------------------*/
5 N. r' D: g2 f0 a# q' h7 q! i/* Private macro -------------------------------------------------------------*/
8 @1 I# B- c+ l& r% [. t) Y- P/* Private variables ---------------------------------------------------------*/, C6 v3 N3 @1 i7 {6 V: ]
static volatile uint16_t USB_RequestIndexI;     // Request  Index In
; P$ O4 r9 H1 M4 c" p5 `3 sstatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out8 w' z5 P; V4 {
static volatile uint16_t USB_RequestCountI;     // Request  Count In
* w8 }5 _$ s7 m& \  D; J0 Fstatic volatile uint16_t USB_RequestCountO;     // Request  Count Out
- c3 q* u7 c6 q1 [static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
9 E3 f1 Q" l' c4 l  C
2 {) Y$ A! a. O, `8 Lstatic volatile uint16_t USB_ResponseIndexI;    // Response Index In
  }( ^0 _% d3 G  C1 H8 lstatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out4 B* @9 H' |- D' Q
static volatile uint16_t USB_ResponseCountI;    // Response Count In, @. B3 [8 H; \, ^
static volatile uint16_t USB_ResponseCountO;    // Response Count Out
9 \0 D  h! M* n/ ?static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
& e/ c1 o- i' C# s. c3 z! ^static volatile uint32_t USB_EventFlags;
9 O2 K! x0 c  c% ]9 w- S" {( m* B( V0 g$ c# v
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
9 v; Q( H7 h, Y  H) bstatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
( X# i! \' e) h. T$ P& y* Vstatic uint16_t USB_RespSize[DAP_PACKET_COUNT];  q: g& e9 R$ [

: C7 E3 c' O4 `5 j* Q( K/* Private function prototypes -----------------------------------------------*/
+ ^, h; {8 L8 }- R! S9 V/* Private functions ---------------------------------------------------------*/
5 m* S# [. _5 s# Z" N( F8 R; c' ~/*******************************************************************************
; O9 j. g1 m( Q6 B* ]( _7 C* Function Name  : EP1_OUT_Callback.  _5 g  q+ e1 o  t
* Description    : EP1 OUT Callback Routine.
$ `8 Q( C7 X3 `$ M2 e* Input          : None.
7 Q( ], B# S  P+ H4 y* N" \" m* Output         : None.
# J: v1 ~0 T3 O/ X* Return         : None.
! D( H+ C) o4 q8 B*******************************************************************************/. ]* h' T( D+ }' y; i
void EP1_OUT_Callback(void)
2 z+ t8 ^$ I# S  \5 e- n{
* ]; |3 j) u  P  l  d* d0 U7 R        uint16_t n;9 E, x# _  H$ V" f6 }

# |' P) s# m$ @        n = GetEPRxCount(ENDP1);; }' n7 L" Q" R9 ~! Z# S; ?
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);! |5 w$ z: [6 |& b" m! U
        if(n !=0){  q7 r, C3 J' T! F! J. W) w
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
3 p" u: c$ ?/ C# z) F9 g                        DAP_TransferAbort = 1U;
: R7 J% t, F- m& O) ~' a! e                } else {9 A3 g! q9 ^6 ^- Z6 ~8 U1 c) U- S
                        USB_RequestIndexI++;
3 S: i, `8 X% J      if (USB_RequestIndexI == DAP_PACKET_COUNT) {0 g4 \& j" _/ l5 c/ P$ r
                                USB_RequestIndexI = 0U;
0 G& B# k6 G2 y/ \      }
- \/ o! o. ?  k6 c      USB_RequestCountI++;: o7 Y- ]* Q+ |, X( o- @
        USB_EventFlags = 0x01;
" z) b# {& ^' q" k    }6 s. W$ K. n+ C1 d2 ~
        }        
0 L5 y  K' V/ u! ]3 w- Z/ Q        // Start reception of next request packet# U% n& Z: l9 r: u5 A7 ~
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
, [9 ^  ]! R5 s; T9 A                SetEPRxStatus(ENDP1, EP_RX_VALID);
9 S" ]1 z. `- T" e# \! u  d        } else {
9 `$ K' i( q3 x' \: A0 A) y                USB_RequestIdle = 1U;
4 w$ }  t$ E& v        }                        - N5 l3 ]2 U  B; h+ d
}
* b' u$ u' Z4 U. }6 s& k4 K5 V  G; F, W, x  d4 q# l: K
/*******************************************************************************4 Q2 q' U$ H) q' |8 m0 V  S
* Function Name  : EP2_OUT_Callback.8 i' i2 ^7 z7 V. v4 U
* Description    : EP2 OUT Callback Routine.
" T' H3 I1 J& X1 W9 Q* d" \3 e, ^5 r* Input          : None.) S( J5 Q+ A9 ~4 C
* Output         : None.
- |* h# s1 _2 g3 K3 ^, ?+ m; @* Return         : None.
" Y; q( A' p9 A% R! u*******************************************************************************/
  l/ C# r; |. u" @6 B' istatic volatile uint32_t TX_n;0 J6 b2 X- i7 C( e" I& x7 {/ O
static uint8_t *pbuf;
, f1 t3 R- z+ F( \% x* Lvoid EP2_IN_Callback(void)
% i1 E7 b, j# ~8 L, q5 c$ G" P{
" i1 j0 R- I9 {. N9 [        uint32_t a;  s# X8 W8 H4 t, ~0 T9 m* N
        if(TX_n>0){
9 d8 }. e# S4 f7 B9 s" I4 G/ H                pbuf+=64;
% f. S8 z+ d1 _0 d                if(TX_n>64){6 I$ _% H" c' i
                        a=64;# y" H  m# U! B
                        TX_n-=64;$ q& E; j0 v: c# _' @
                        $ c5 a4 F0 E! |6 a6 ]4 _
                }else{5 f# }! m& ~' k( T- `( M! T+ o& y& H# m
                        a=TX_n;/ f( J: b* A9 n3 {' f
                        TX_n=0;
; A0 e0 E/ |' s  k                }
" |6 l, L  f' _7 W8 Y+ ], D                ( F" i1 d5 u2 }% b: ^
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);* H8 X6 \3 c, R7 p( `4 p
        SetEPTxCount(ENDP2,a);
; A# Z" ]) q. }# x                ' X0 V  y3 j" v3 q5 T  W8 m
        SetEPTxValid(ENDP2);
! h4 B/ Y0 Q3 A        }else{
5 Y$ g; Y5 G1 X  f9 B. ~. z                #if (SWO_STREAM != 0)
! W' K, ?" A/ S6 {                SWO_TransferComplete();6 o5 C+ t( m- s
                #endif
- D" Q! [+ I: E1 b6 y5 t& P        }3 W' k! W4 T- A7 D# Y" r
}8 }, F$ j1 Q" H9 l+ Q! O5 h2 p
, {. g* |, u1 g# {* k* k  B) X
/*******************************************************************************
' T3 l' ]; m' q+ y+ T% E, j* Function Name  : EP1_IN_Callback.5 v, g1 r8 d! t5 G; S
* Description    : EP1 IN Callback Routine.
* C$ s( ?) D% J* Input          : None.. Z  `# O. z* S0 _% F: m" x
* Output         : None.
3 G3 E, r% F- h. [' O+ g* Return         : None.
& d% s& r& I( f0 R& V7 n0 E& P7 ~1 T*******************************************************************************/6 S8 b% b, f( z, W+ W
void EP1_IN_Callback(void)7 S. {; n8 j4 w, c+ f% {" o: v
{
* D# B+ e% [( h" T; Q$ G    if (USB_ResponseCountI != USB_ResponseCountO) {; U" d" ^6 ?8 G; s
      // Load data from response buffer to be sent back
. c1 U  \  S8 Z8 ]/ Q                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
1 c8 b/ q: I/ V: W# v/ m3 W9 y                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);- `$ g( r6 t+ ~
                        SetEPTxValid(ENDP1);                        
8 r: S! o* {0 W( Z3 g/ F      USB_ResponseIndexO++;2 i$ L, y# I9 u% u" l. W1 C
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {, v+ y+ N1 G' }% d
        USB_ResponseIndexO = 0U;( a7 W: T9 W2 G
      }$ s' S5 }# E3 h& |; B1 a
      USB_ResponseCountO++;4 @& h; ?0 q: H6 p& ~$ `
    } else {
# M" _1 v$ W& m/ [3 t6 H      USB_ResponseIdle = 1U;$ H6 I* _1 s: J* z5 J
    }  
/ H- V$ j: O  V. v  Z' @}
; w/ x) Z  W9 D% d* F9 C
- _& N3 F1 t7 x& m* ]$ P// Called during USBD_Initialize to initialize the USB HID class instance.+ \6 l3 W4 A, j7 r& Z# M
void DAP_FIFO_Init(void)
' X+ P% f1 z" O{0 L( K) `* W& h1 s. I1 n
    // Initialize variables$ l) E- T5 \& h9 e
    USB_RequestIndexI  = 0U;
( H! Z. g0 R0 [) G) E    USB_RequestIndexO  = 0U;
, v2 Q! S2 F; @) M' f    USB_RequestCountI  = 0U;) X; ?  D/ l& G( i/ W
    USB_RequestCountO  = 0U;4 _, V1 O3 ], H" ^8 q
    USB_ResponseIndexI = 0U;1 B" ^/ I4 f- M3 t% Y; y
    USB_ResponseIndexO = 0U;
( u; B5 z8 f  n" M    USB_ResponseCountI = 0U;; N8 P5 g$ y+ u5 J7 t
    USB_ResponseCountO = 0U;7 ~" |  a  |1 z( O( a! d
    USB_ResponseIdle   = 1U;+ U- _2 p* S, ~
    USB_EventFlags     = 0U;
! T1 }3 l1 N0 g  }}
* r0 @  M- q  ^9 r4 Z
* N. K! Z' [3 e) q% R+ luint8_t DAP_Thread (void) {
# i6 |4 T$ w. Y2 X  uint32_t flags;7 F" L4 T0 k* m1 R+ q+ t
  uint32_t n;0 r9 O4 C. y; m* i) c* V) {8 K

- Z% k) @) n0 b  //for (;;) {
3 D' y4 V$ K% y+ L2 l% x0 b  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);& y$ X6 _$ ?) D) ~; i& p, N
                if((USB_EventFlags & 0x81) == 0)2 J, T3 C0 {7 \2 x# w
                {5 e4 D# J# R. U' ?
                        return 0;
; c! |( ?* Z* {1 N$ s7 c! ?' _                }
2 \5 S% j8 r1 B& n& v( J# t                USB_EventFlags &= (~0X81);
: S, {+ l2 U& ]% S4 q# `0 i0 j  d                  ~3 i3 [) A- b6 C8 T! s+ E
                                        ( }7 g/ o& ~2 b5 P. x% H# F
    // Process pending requests4 H* L$ K0 t0 Q" b: S, y( d
    while (USB_RequestCountI != USB_RequestCountO) {: o2 C4 A  n1 d
                //if (USB_RequestCountI != USB_RequestCountO) {
: G, O; y& W; g! T; D      // Handle Queue Commands
4 }% \$ n! U* t7 X8 F# _/ ]6 O( t      n = USB_RequestIndexO;
6 ^) [" @8 W/ D" p1 }9 A$ Z      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
0 g  K/ _( Z' m  l7 l/ e                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
% c8 b3 P2 l- s: Q; W) z        USB_Request[n][0] = ID_DAP_ExecuteCommands;
" g: P3 p' ^8 f% Y        n++;
  t9 \  q, K; S; t' F, K        if (n == DAP_PACKET_COUNT) {
4 x9 q8 \& c2 I! U) n) _$ o          n = 0U;
! n9 E; B; U* z! j, U        }
# z( @2 z. a. A  e- f        if (n == USB_RequestIndexI) {
  a7 L. E: t, w; ^9 _; t- e  y          flags = USB_EventFlags;' o! b! I( `- P& e+ s% n0 u4 z+ M
          if (flags & 0x80U) {
' I  S3 O) Y# D$ t            break;
3 U; B* [* ~/ @% s( [          }
: _4 }& c8 N, z        }5 T! {( W) T8 @) L1 H- R
      }
, ^/ J$ D: F% F$ U. N! @- M2 E5 |( A$ L$ z: ^* N3 P. u+ q
      // Execute DAP Command (process request and prepare response)
$ `; C. J0 B2 ~- r      USB_RespSize[USB_ResponseIndexI] =8 ]6 G5 T+ C! ]) P" ?
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);- X: b7 ]! ]* C* `$ N0 c
6 @$ x7 H9 O' K: u4 V2 M
      // Update Request Index and Count' [# [) F0 O0 u) E! {! x& s9 ]
      USB_RequestIndexO++;/ `( U1 S, L& V& d
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {' S' [$ E4 D& c9 K# Q8 b+ v* ?
        USB_RequestIndexO = 0U;
1 j/ b2 z, A8 k8 c3 {) G# I      }
* _9 W9 R) b% F5 j      USB_RequestCountO++;
+ G8 ]0 N; S9 y. I
) N: W" I2 I$ R- Y. f) K9 e      if (USB_RequestIdle) {6 p& R* R  h# o: ~! J9 r
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
" _) i+ t9 x- m. V          USB_RequestIdle = 0U;
' Y" s! b" \1 }          SetEPRxStatus(ENDP1, EP_RX_VALID);
" s- r3 U5 c# ^2 P: q6 P        }
2 C$ [; e- e  o3 Y* B      }
1 R) r6 v/ o9 Z  X* K; D4 F  M) z+ F8 d2 _& M" d. i6 p" ^) h
      // Update Response Index and Count7 e. t3 W$ c- h' M" {% ?
      USB_ResponseIndexI++;
+ c* s1 }2 F* v/ L      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {; a# g' }; B$ f. l+ B
        USB_ResponseIndexI = 0U;; D! E% F+ d, T# a) ~
      }
# U' L- W0 x! F5 y6 d; S& m      USB_ResponseCountI++;$ y8 [2 c# |4 u6 b2 p6 S

+ ~, d) C) ?- w! u3 {: j      if (USB_ResponseIdle) {1 q% y. Y8 H6 B1 Y
        if (USB_ResponseCountI != USB_ResponseCountO) {
& X9 ?( w$ m+ R, ^! f1 h0 W          // Load data from response buffer to be sent back: N8 i- g5 G8 \. M/ K
          n = USB_ResponseIndexO++;
7 Z! B; ]3 R( X9 H          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
# e  D" p2 y% ~; z9 E6 s: A            USB_ResponseIndexO = 0U;/ ^+ H8 Y6 x% t, Q6 |
          }: B' T7 V$ F$ Z1 u- K, y! j
          USB_ResponseCountO++;
0 h' ~- U1 R) i$ G* p0 _! h# x          USB_ResponseIdle = 0U;
5 q: O; G4 D- A: p/ t- `          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
3 z1 }4 _  I, g7 M# a( ?2 C                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
- a, j5 |7 w  t) z; M1 X                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
, T, l) M6 X" i' d& j                                        SetEPTxValid(ENDP1);
, j8 H( V5 f, t        }
0 l) ^# Z* ~& O3 B      }  n; ^; R7 |+ }' @7 h
    }
  Y6 C7 O) [1 H! a* N: F6 A        return 0;
5 N5 u* V* `1 r% J}8 p* I! o4 K; {  U; k% R

$ u) a- y3 P. i8 b* I* X3 {7 @// SWO Data Queue Transfer
% q+ e9 q4 R& l& F% h& w& f7 m//   buf:    pointer to buffer with data" ]; V5 T; H; e+ s8 {, s8 O7 R/ g
//   num:    number of bytes to transfer
, `/ X+ F. i, |void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
: @8 y7 y3 d/ W  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
- M; N3 L# `) s* B' [& e1 N        uint32_t a;+ k/ O8 T2 B6 F; c, S, T# n$ V
        
$ D' d- e) h8 ?$ W# t) p+ [        if(num>64)
3 k+ Z! |4 E, F) ?        {1 g4 y& h$ J. L6 _  R' }) N
                a=64;3 ^% o: B# Z  r6 b. W
                TX_n=num-64;* a9 f3 q; F' c
                pbuf=buf;5 r$ d. _) }) z
3 F8 ^) m7 z* q1 k
        }else {4 [& h9 ?% t- H  M, E( a
                a=num;
8 M, p. v5 x/ L  B. K                TX_n=0;2 l% b, C1 m" E
        }
3 @4 N  `% l% [) }9 g2 E  K  S8 w        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);- \/ f: F, ^: \7 e
        SetEPTxCount(ENDP2,a);
, z1 ~6 V, a6 O, W; h# ]! L2 Y        SetEPTxValid(ENDP2);6 E: I+ M# i+ k4 K+ |7 X, @9 a( g
}  m+ p  ^: z6 J3 E" g% w9 y
& B9 N& N% I' M0 g
// SWO Data Abort Transfer
8 F) z7 x8 A2 i$ \void SWO_AbortTransfer (void) {
2 I  c( |/ i6 I+ |' p  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
3 X$ X3 ^7 \* |& g) s        //SetEPTxStatus(ENDP2, EP_TX_NAK);$ q8 c% G8 S) {2 n7 J
        SetEPTxStatus(ENDP2, EP_TX_DIS);
5 W' K8 S! I; _; o        SetEPTxCount(ENDP2,0);% i0 u! |- Y' ^& F  @
        //TX_n=0;
& w5 u% H/ B9 T: b2 B' F' p}
6 L" E' ?: W& I6 k+ C/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/9 b! a% u/ G- f

' [7 |4 D2 K- n- [3 z  H$ J移植大概是这样的,利用STM32_USB-FS-Device_Lib_V4.1.0里面的例程Custom_HID修改为自定义USB设备,3个批量端点,OUT,IN,IN,由于批量端点不像HID哪样要使用报告描述符号,但要让WIN识别出驱动,添加了WINUSB相关的描述符号,在端点回调里实现DAP的FIFO处理,然后把DAP_Thread里面的线程调度修改为标志通过,放MAIN主循环里调用,测试SWD下载程序,调试都完全没问题,时钟设置为10M时感觉速度还是可以的,这能体现批量端点的好处  q! O6 a- G8 z3 H9 e
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了  `6 o3 z% P- r/ Y& Z
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {8 j* R/ N4 `+ L0 y. Y; K/ M; ^
  return (DWT->CYCCNT);
( Z4 P. r5 V2 t/ m}: x* U3 H, ~" l6 t% N) e
1 ?9 s9 l& o: X6 N$ G% f
void DWT_Init(void)
  D% M8 a8 m# w# {$ T4 V( {{
: B7 {) S$ I+ c- S0 J7 g/ e    /* 使能DWT外设 */
6 p9 y" V  O5 |    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                4 U, B7 x% |6 a& k& I

% Q5 ~' {, d% L  D' I, Y' v    /* DWT CYCCNT寄存器计数清0 */
: c2 |7 w9 c. I" C! A    DWT->CYCCNT = (uint32_t)0u;3 W6 H( g  ?& G* l0 Y1 E. P8 n
# j& P# D7 T1 b% X
    /* 使能Cortex-M DWT CYCCNT寄存器 */
- z7 ]3 [3 P# d( U# c    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ e  w, U( m3 p7 a5 x7 I}
$ m# x5 a4 ?$ T$ ?$ f+ Z/ e- L        
3 S3 j6 S% P/ n3 H8 W5 y% w5 O& N) ^- B0 H$ G3 T1 q; l/ ~. {4 p3 d  z
然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
9 d( _. y9 ?  F  ^- x! m
6 G, ?: W* p- d; c- e, {) t然后改为使用SWO_STREAM传输方式,这种方式是单独使用另一个IN端点进行传输,即DAP的命令调用SWO_Data时只取走了SWO的状态,没取走SWO读到的数据信息,数据信息通过SWO_Thread通过另一个IN端点发送出去,SWO_Thread也是把线程调度修改为标志式让行的方式,对于50毫秒超时处理部分没弄,就这样放到MAIN里的主循环轮询调用,换了这种方式后,SWO单步调试,全速下也能打印信息了,而且全速下不会是卡住了,响应速度就与没开SWO时一样的效果,即没了被阻塞的感觉了,非常爽快,所下的断点,按一个F5马上能停止,非常快的响应速度,但有时候Keil底部状态条会提示Trace:dataOVERFLOW,查了一下这提示说是SWO端口读取太多的数据,导致被截断,具体也弄不明白哪里问题,另外手上使用的自制JLINK V9,开启SWO时,SWO时钟是6.XMHZ时钟频率的,而且连接上芯片后,打印信息啥的都正常的,而且不会有报错等待问题,在想这会不会JLINK的SWO接口是使用SPI做的,毕竟串口这个时钟频率能正常工作吗?DAP里的SWO能否改为SPI接收,因为不使用SWO_STREAM传输时会被阻塞住,很大原因是串口时钟频率太慢了,这估计得研究一个SWO的接收协议才行,个人来说SWO方式还是比较实用的,有人会说会占用一根IO,但要说使用串口进行调试不也是占了一个串口,但又会有人说JLINK的RTT不香么?0 g0 d3 C6 C  d- O# h, x# a; ~
声明这个变量static volatile uint32_t SWO_EventFlags=0;% ?' ]! i# c7 @7 k+ Y
在SWO里每一处调用osThreadFlagsSet的地方都改为如:: B; P* o& B% ?5 u
//osThreadFlagsSet(SWO_ThreadId, 1U);" [7 s) L. }6 \  `: F7 K) b
SWO_EventFlags = 1U;
. Y, t/ N# E  E  p$ V  N8 j) {$ t, e) @% G$ I4 a4 J
! [2 l9 z& d. r6 `0 q8 {
// SWO Thread% H% ^$ f* X$ @5 o% ^5 Y3 S
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
9 |) E" c# t& d/ U5 g7 A  //uint32_t timeout;. m) G' ?0 i8 g6 d% T, E/ [
  uint32_t flags;  x9 n' Z. G; H
  uint32_t count;
- @  L+ h" e( V+ }, }2 {. R6 L) _  uint32_t index;$ y+ G" v) a) i! F- u! y
  uint32_t i, n;2 E" \' \% M: Q4 |$ t4 u5 E
  //(void)   argument;# \, Y* x. @+ ^8 p6 S

8 F' K! J5 G3 x  S# q, L; `  //timeout = osWaitForever;, f+ q& A( d( F3 e) _1 H
9 m  q: ]2 G5 q7 V
  //for (;;) {5 h+ D! \" g0 j* l' [
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);2 ^( Q) r- c4 w& c( E- C
                if((SWO_EventFlags & 0x01)==0)return 0;
6 X" P* k  x3 P8 `- z( b' u5 h: O         : G% }. P1 e0 C7 v7 L
                flags = SWO_EventFlags;7 R7 Z8 w5 `/ ?9 j* s* s
                SWO_EventFlags = 0U;
! W7 Z) M4 X5 W# n    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
' N; v/ [3 T% R. D  ^      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子. e: Z2 J0 d& l7 y6 v! h% k
                        ;8 x$ e$ g6 G$ l0 f8 {2 e) ~
    } else {! M  n8 _% P* R3 w9 f5 F
      //timeout = osWaitForever;
1 x, f. p: U& _+ e7 \; S      flags   = osFlagsErrorTimeout;9 \4 s1 V4 X. D4 q
    }* ^, I0 m/ ?. O0 R6 G) \. x
    if (TransferBusy == 0U) {
- \! a; |1 G* N  m5 |      count = GetTraceCount();! ^) F: l/ T7 _! t7 |
      if (count != 0U) {+ D5 }& e: f9 D$ i- q" C5 k3 H
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
8 X8 [( J) L1 _        n = SWO_BUFFER_SIZE - index;
! D' h; |  ?1 k8 k' L        if (count > n) {. l( M% w5 N% S: ^7 F
          count = n;
0 M' b2 @1 [6 X* D' n/ h9 L: Q                                       
0 m& e: W/ F3 {$ X; e" J1 B        }. M4 a- R$ r3 Q2 [  Z# g  M
                                if(count>USB_BLOCK_SIZE)- d& |; I" m6 J1 E- `, K
                                        count=USB_BLOCK_SIZE;- {5 e2 z& ?( ]  _& n
        if (flags != osFlagsErrorTimeout) {
' E- [+ i/ X' ~& _- r- [: J          i = index & (USB_BLOCK_SIZE - 1U);
* Y6 ^7 Z' ]. X9 z' z          if (i == 0U) {
& _2 k0 i/ ]1 }5 w" |' m# `            count &= ~(USB_BLOCK_SIZE - 1U);
( ]2 k% m" G- Y8 p4 N          } else {% [, l' @# s# p  B0 R
            n = USB_BLOCK_SIZE - i;- \' m) q. x6 g
            if (count >= n) {7 I. G# o  O  a* M
              count = n;
7 b& ?4 [4 l1 g; ]' \0 S            } else {' n* j/ ^) D& e
              count = 0U;
" w7 M# Q6 I# Z6 ^" t) I/ A% p1 J: ^            }
8 E9 K' J6 s; u) L# D  L          }
  Z" M2 R; x1 f: ]: i' L% W        }$ i( y0 r. y$ i  l
        if (count != 0U) {8 u! T3 \4 \9 @- D5 L
          TransferSize = count;; ]( C2 f9 a- q% e$ a  F
          TransferBusy = 1U;0 g! C1 O# z5 }, T
          SWO_QueueTransfer(&TraceBuf[index], count);
7 `; n3 Y+ D% e8 B; d% y        }2 {% S) E3 g" M
      }  @& Q, p5 A( m5 ~
    }2 l6 ]8 ^: Q! T: A8 j8 T
  //}/ m9 f4 i0 _% J4 g. [+ S
                return 0;
" M7 |5 c3 |6 [9 `}
( U9 S4 p- P+ C0 l3 P7 ]# q( ~8 i0 v利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.- W; X+ b8 _( |1 w
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
1 D* Q: Y7 G* n% g, R0 }( qstatic volatile uint32_t SWO_EventFlags=0;! r7 Y! k1 b+ Z" i: M* _
static volatile uint32_t timeout=osWaitForever;
* \$ e) g6 w) Dstatic volatile uint32_t timeWait;
$ S1 t# h- ^" j/ C$ B函数改为这样. p. g' u' z3 D) h. x, Z
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {; O0 e- ]5 \6 |5 m* h: [% I4 L# T( r
  //uint32_t timeout;3 }4 D- A& S. s0 O
  uint32_t flags;
& _9 J8 p% r9 b  p. o  uint32_t count;
* u3 g! q( F: J& _  uint32_t index;
. x. F! g& W1 r; F7 u' m; j  uint32_t i, n;6 I; q! c1 I1 f) {3 M
  //(void)   argument;
, V- h" u1 t8 l  m" j. ~
( u/ e& p; ?) h, b  d( X; Z5 d  //timeout = osWaitForever;8 l  o, y9 _8 P5 B

+ Q  @$ {/ \  c9 @7 @  //for (;;) {
' R- |: W0 w  m* }1 }, U6 E    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
! S5 x4 a+ X: O                if((SWO_EventFlags & 0x01)==0)9 o. F* ^3 H, |
                {
$ }) _6 `7 E$ ]" i1 [                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
0 w0 e1 W3 A! Y  p' J3 `& x. o                        return 0;
7 n+ ]( P- ^- W                        
3 r7 _4 j% a3 {" A% r1 p; i                }3 U. ~+ q, u: u. |7 \7 U
         
& |" R" j/ ?7 B/ {/ |                flags = SWO_EventFlags;
. R9 q. d5 E- Q6 F                SWO_EventFlags = 0U;
  {4 ^0 N+ ~" U& W/ {    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
! F" M  x9 K7 L9 M5 [6 z% g      timeout = SWO_STREAM_TIMEOUT;
, q5 V, P( o' ^* P1 j6 a% e3 y      timeWait=DWT->CYCCNT;
7 n( L" n' R: d8 q7 D5 p    } else {
# C4 P5 \0 C% o6 H- L( g; X% }      timeout = osWaitForever;' h' @1 G7 y9 Z! J; d# v
      flags   = osFlagsErrorTimeout;
( z4 {6 [4 U1 B, D* T6 v    }* O- }* [* B5 e  C. x$ [
    if (TransferBusy == 0U) {
% U) O. k; t* `5 c7 c      count = GetTraceCount();
) v5 u# O+ P% Z6 g; `      if (count != 0U) {
/ R# W9 D: ]; U: q4 g: r; h* V        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
  S# U# p& x* t9 o. J, j        n = SWO_BUFFER_SIZE - index;
2 G" x- Q# v1 i$ }, b        if (count > n) {
- J5 u! Y/ v2 v2 B) `. ~          count = n;' N3 p2 t' d2 f6 {
                                        # A0 z3 p! D( R; ?- S2 W) O8 L
        }
6 n5 R$ @( L& o* {+ K1 q7 o                                if(count>USB_BLOCK_SIZE)
' h; T, Y: C" Y. N; H                                        count=USB_BLOCK_SIZE;
# _& C% W7 i- x8 V2 j8 R        if (flags != osFlagsErrorTimeout) {
3 _+ Y, Z# _1 O8 \          i = index & (USB_BLOCK_SIZE - 1U);
# E) `8 @" j$ `, c3 m- s2 K          if (i == 0U) {  P% h' E' i% s* ?" T, M! E
            count &= ~(USB_BLOCK_SIZE - 1U);( M0 x1 N& |2 @9 p% ]: p
          } else {
0 C7 P1 ]4 ]7 m- Q            n = USB_BLOCK_SIZE - i;
) X3 ?$ ]0 E- W8 Y- n* y% g0 @' h            if (count >= n) {! ?% P5 E* u! P; ]
              count = n;
- _0 [  @& Y' L5 G# ^            } else {
+ o8 N; |: H' o5 k8 K' R              count = 0U;, x4 a1 m- o+ a$ k6 f$ ?+ |
            }  a4 k! t0 |5 B
          }
& D, s+ k  H+ S1 ?( ]        }
% B& A" l9 Y( J        if (count != 0U) {. f5 i2 Z# p' G) S
          TransferSize = count;
  t: ^' L6 V% _          TransferBusy = 1U;( m8 _/ [; S: l! S
          SWO_QueueTransfer(&TraceBuf[index], count);# ]. b; C0 v) J/ [: H5 |$ ~
        }
( q5 b3 ]" D8 p- `) h; |8 [      }
: [6 [. ^/ ~7 |$ M; ?; I! \5 E# e8 O    }
! r5 e5 {6 d7 g! T  //}
6 a1 b- S. E( q7 H9 D: U7 c                return 0;2 Z/ z3 T- Q& D  G( ~
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了
1 f' H2 h) l$ v% _! M3 L4 U( e
5 W6 |& F$ F+ U+ z. q/ eCDC部分暂时还没加入,SWD现在是非常稳定的,而且速度感觉也是不差,就是SWO的问题不知道如何弄,另外看到其它人弄DAP,把SWD读写部分改为SPI,看了一些SWD读写协议,它好像有一个8位一组和32位一组的部分,如果换为SPI是不是就可以更快的速度读写了,另外DAP与USB之间的FIFO部分它有一个队列等待,看意思就是当有标志着队列的包时,就等待接收更多的包缓存后再执行处理,对于批量端点,连续的传输大量数据确实是批量端点的长处,因为批量数据时,端点接收完一包后不会NAK,端点会接着接收下一包,少了一些中间商的处理,也尝试过这个队列等待修改为不等待,即接收一个包,执行一次DAP处理,它同样是能正常运行的,对于批量传输来来说,感觉应该队列等待会提高USB传输的速度,比如下载程序时,Keil 一次性下发多个命令包,比如达到1K或者2K字节或者更多,DAP先全部利用批量端点的优势一次性接收下来缓存,然后DAP才执行一个个命令包的响应处理,对于读写部分构成字节为一组的就使用SPI读写数据,零散的位部分像ACK,SWD复位等待部分用IO模拟来处理,SWO部分感觉如果能修改为SPI接收估计时钟频率可以更高,这样响应速度更快,另外STM32_USB-FS-Device_Lib_V4.1.0固件库的USB端点没有FIFO,不像OTG USB FS 库哪样端点都带有FIFO,但是提供双缓存端点,准备把端点修改为双缓存的,这样当连续多包传输时,端点就不会NAK,少了这个等待时间,能增加端点的传输速率  K: z  p3 F6 d6 p
' a  Z( ], b; i" r/ _

, ?: u1 J) o1 xint main(void)
! I. Y1 h$ s5 C% r- W) [{# c5 z3 R! `; ?& Q
  DWT_Init();
9 m: ]+ i2 V, w0 a        DAP_Setup();1 I. a3 `/ A  x+ \
  USB_Interrupts_Config();5 R2 u, G4 n: e2 x+ l
  Set_USBClock();% y6 m' f5 a% p. O% U3 m* v$ V
  USB_Init();
- _$ k+ @% D- K0 |        //TIM3_Init(35999,0);
9 {5 G  w8 s& n  A% F! n% h        //TIM_Cmd(TIM3,ENABLE);
/ U$ x0 z) D( i; X        . G8 Y. u$ B) J! n+ z2 B: m; n
        
1 T) \5 |. K7 A+ Q  while (1)8 W1 T6 Z9 I0 Z
  {9 U" X- P" c, ?
                DAP_Thread();
' q+ E8 J* W7 Q! L& q                #if (SWO_STREAM != 0)
" X. k% a" N( l) q                SWO_Thread();4 n6 b8 r, y  E5 c: }) K7 C3 j8 N
                #endif% y$ X) y; G3 b( ~$ a& w& }
  }: y1 z  o3 z4 P" G  D( i! u
}6 \3 D8 D! Y9 ^
' U8 Q/ _: Y) d
对于DAP_config.h的IO配置我是这样弄的2 J; C3 F: f+ ]9 n2 s, G
///@}
7 Z) o7 n6 z- f6 h& M- v// Debug Port I/O Pins
6 g" O# Q. o2 Z: k3 p9 |# }$ F% e, p0 Q+ e+ {: c1 T+ ]
// SWCLK/TCK Pin                GPIOA[6]
1 q) }2 a- z4 J6 i3 a7 j#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198" w1 F( R3 t* @4 {) H
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
. q, F+ W" D  ^5 n3 d' P
. ~' G# o" ?$ R: T4 ^// SWDIO/TMS Pin                GPIOA[7]- x" W6 N5 W) i7 `- ]
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
0 h5 _+ V7 q8 t2 x. t4 g#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C2 h3 A+ A+ e. @% [( d5 X/ b
/ P+ K; C2 j1 C- M; M- }: \0 l
// SWDIO Output Enable Pin      GPIOA[7]
! g' N5 G: q4 O. j1 g" h* ~#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
2 u% _* [* ^  c* n% _                                                                                                                                *(uint32_t*)0x42210070 = 1; \
' V9 \( a. O8 {$ h                                                                                                                                *(uint32_t*)0x42210074 = 1; \
1 w% `/ M8 G# x; f. x8 ]. k1 G8 ~1 E                                                                                                                                *(uint32_t*)0x42210078 = 0; \3 o1 f4 ]' M; q4 |& r
                                                                                                                                *(uint32_t*)0x4221007C = 0;}
! L! f5 c( W( O, I; W% G0 J5 C; t
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \+ \  l. Q; E* f' q3 I, M2 J: g
                                                                                                                                *(uint32_t*)0x42210070 = 0; \1 W6 m3 X% c3 ~/ r0 E0 y
                                                                                                                                *(uint32_t*)0x42210074 = 0; \
" S* y/ ]5 k. t                                                                                                                                *(uint32_t*)0x42210078 = 0; \) s8 j0 f3 b( K2 ^& a  ?
                                                                                                                                *(uint32_t*)0x4221007C = 1; }8 _2 `  q% @2 i9 _4 X: u( P

! h3 o. U3 p6 n1 x4 M// TDI Pin                      GPIOA[8]* ~3 P( f5 m) N3 a1 {' C: ]! F- @
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
+ T( X! W% l: _5 Q/ f6 Q#define TDI_IN                                     *(volatile uint32_t*)0x42210120
: i, `3 Q! R6 M0 F2 b& ^2 ?
$ S4 V- I! Y+ H! R2 s// TDO Pin                      GPIOA[10]
8 C& G! n/ X7 P( A* ^+ J#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
# ]( b- u# d& h& e, G#define TDO_IN                                     *(volatile uint32_t*)0x42210128$ R3 Y6 R: X; I+ ~- s

2 U: [6 N" a# c// nTRST Pin                    GPIOB[3]+ d+ {2 Q$ _2 b) _- N2 g3 G* P" G
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C8 x; c# E5 e7 h
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C6 C6 D* G8 K: l. U$ e

. }' Z( H# ^& [8 k: ^/ W// nRESET Pin                   GPIOB[4]( R' b7 m' v% y7 N! R
#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190+ m5 M* s  l6 \! t5 v$ E
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
, Z$ p9 s) _# j( U/ }5 o' b- V/ S& v( }* b  r$ k
// nRESET Output Enable Pin     GPIOB[4]; e9 D  ~: p' ]# o
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
0 L5 k" }# v" P; x  X                                                                                                                                *(uint32_t*)0x42218040 = 1; \
) z! K! ^- h2 }8 r  I                                                                                                                                *(uint32_t*)0x42218044 = 1; \5 h' }& l# G+ i) c9 Z
                                                                                                                                *(uint32_t*)0x42218048 = 0; \
6 p5 X' f) [4 X; T4 }4 v                                                                                                                                *(uint32_t*)0x4221804C = 0; }
3 q1 M( J: U4 A/ q9 m' H7 Z! J, V- {
* ]$ Q4 P: [% t. F#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
/ Z2 @  k. z; C) k3 w8 M2 o                                                                                                                                *(uint32_t*)0x42218040 = 0; \
( \$ A6 c) @1 r% d5 q3 s                                                                                                                                *(uint32_t*)0x42218044 = 0; \
# G) U: v4 n. \' b" R                                                                                                                                *(uint32_t*)0x42218048 = 0;\5 C( ], N) C4 d; f" O( a6 {1 y
                                                                                                                                *(uint32_t*)0x4221804C = 1; }
6 j- z1 W: S, _& q' Q5 `. C0 m+ H; e
; X5 O7 g* o5 E- x5 M6 ~' ~/ f# Q8 h5 I( k2 D& H) A
// Debug Unit LEDs
5 p* P* P# J" k0 u) q. m4 X; e, S" r
// Connected LED                GPIOC[13], _& l8 u% v. s6 i5 N
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
9 V2 ]4 _  i+ l; ~#define LED_IN                                                       *(volatile uint32_t*)0x42220134
* _$ }/ I& d0 G% _$ ~& p% J. S) y* g7 o) P5 x9 `
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
! ~: ~4 z: p# T* B                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
, ~$ c1 B& d; S; [3 V                                                                                                                                *(uint32_t*)0x422200D4 = 0; \# ~  }/ b9 H( K' w1 y6 ?
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
# T) C1 M& D$ Y9 j                                                                                                                                *(uint32_t*)0x422200DC = 1; }6 |* q9 K* \! s2 H+ K, v# z
// Target Running LED           Not available+ Q' N: E6 Y) K: i  C9 U
+ u* ^- x% s) y" v7 a
// SWCLK/TCK I/O pin -------------------------------------" _' f  N7 W! I& W7 [/ ~4 s
# A. b7 v' b! I$ S6 i
/** SWCLK/TCK I/O pin: Get Input.
/ ?9 a, r/ t$ k8 E$ c. V\return Current status of the SWCLK/TCK DAP hardware I/O pin.
- [% T+ C+ q' w* K- a*/
- F. u4 K$ b0 T, A! B; q+ J__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {" t( ?' y/ _: e1 Y8 ]
  return (SWCLK_TCK_IN);& }2 ^; q+ y& m, S
}
' J4 C, p" z' f; J6 U8 i0 `3 M4 l, m
/** SWCLK/TCK I/O pin: Set Output to High.; [0 E. y9 d  \4 s: `( T7 b- P
Set the SWCLK/TCK DAP hardware I/O pin to high level.# d: {# b% J4 U$ X) |$ z' H& ]: m+ X. _
*/
( _; Q0 T2 \* \# f3 m__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {1 l8 Z0 O1 h; Q/ I) U9 i
  SWCLK_TCK_OUT = 1;
/ U7 v- [7 {0 ?' U2 m}; z" J% w# u9 Z+ y  N
. S/ R) N9 c6 |$ R! ]: {4 o& D, ?! I
/** SWCLK/TCK I/O pin: Set Output to Low.
$ P: R* R# P9 R, z6 N$ VSet the SWCLK/TCK DAP hardware I/O pin to low level.
% E' h2 t/ \  M: p) Q+ y*/- k( Z  ~% g# ?! [
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
1 R. f* B2 E) w. F9 C) w  SWCLK_TCK_OUT = 0;2 V7 d4 Z6 p! d- ]
}6 E  }  M0 q2 i; {

, l, m& K) M5 @4 H* M5 t: C% X, w. j1 |0 V# W7 a3 `& ^
// SWDIO/TMS Pin I/O --------------------------------------/ t( u: B2 e) k; q; G9 l* f* T
* f- r. A3 @: C" D& M/ q
/** SWDIO/TMS I/O pin: Get Input.
) L: e3 h( O8 p- R- \\return Current status of the SWDIO/TMS DAP hardware I/O pin.% S; @/ c* s0 \3 I5 o" C# x
*/
; K# q) v" E5 }9 G; L__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
% v% z0 J$ s6 ]2 g8 x! W+ D  return (SWDIO_TMS_IN);
3 c; I- S% \& ?}
( ^) q$ @9 e# Q
! V+ G- p9 d7 z' D: B8 i/** SWDIO/TMS I/O pin: Set Output to High.! W" x1 \* F$ Z9 L) _1 Q/ R6 T( t) h
Set the SWDIO/TMS DAP hardware I/O pin to high level.
; C2 Y- J" z' R*/4 v' {4 l$ N4 k9 ~
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {9 v- \+ L9 [) M" F8 Y) I4 y3 d6 [
  SWDIO_TMS_OUT = 1;$ F* S* K2 X* i. |' F& d) L
}
! F3 [5 o2 \" g/ x. r9 L6 X( ]3 ~* A" z8 P; X; d- t
/** SWDIO/TMS I/O pin: Set Output to Low.
/ P7 B  A: [4 X& E, o* E- tSet the SWDIO/TMS DAP hardware I/O pin to low level.
; H6 t" o8 f9 ~# R0 L*/
" V! `8 G# C4 o6 v! G4 R+ A__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {. ~' Q, S3 |. F$ p# O# k
  SWDIO_TMS_OUT = 0;- d- l0 a8 j+ [" z
}8 \( C2 m2 w4 _5 q8 W; ~. O" ?- S4 m
3 n3 A) A% g8 H& j
/** SWDIO I/O pin: Get Input (used in SWD mode only).: b8 x# P8 }6 b- h3 O% W% Q3 Q
\return Current status of the SWDIO DAP hardware I/O pin.% N" I" p5 a1 U4 d# ]' m
*/1 B( N  n' j8 m% ]3 H$ e1 E: I  m) H
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {* q% V: F' [( Q
  return (SWDIO_TMS_IN);5 @: u7 ?0 ]5 M% M$ z
}# ]' i3 I7 V5 p/ q

! @! f! F9 z$ ^) k+ [! L' v/** SWDIO I/O pin: Set Output (used in SWD mode only).
; q* L2 R1 e8 N) E) L' z\param bit Output value for the SWDIO DAP hardware I/O pin." d0 f$ R/ ]  r
*/: y; p8 ~5 s" q( v
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {' {! l, u9 t  ^' N! C% o# ?8 b
  SWDIO_TMS_OUT = bit;
9 z# I7 e' Z1 k( [) B2 c}
  }" n( x0 ^( A8 Z
) B! g, {6 S0 @, W2 k$ Y7 S9 @- d/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).5 `7 M) q7 w* U  i
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
1 \6 x& j' c, z: acalled prior \ref PIN_SWDIO_OUT function calls.
" C- W+ d! y2 ~*/
( F. a( l2 x( P% Q- p: Y$ F* ]8 v__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
' X% b; i- Y+ n1 Q4 b  SWDIO_Output();# R: V0 _+ T* [5 d9 T+ T
}# g1 U$ E5 u. s3 i# T' K  U

% j0 f9 c/ C/ [1 P! U0 _/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).5 A' M5 q# p* N
Configure the SWDIO DAP hardware I/O pin to input mode. This function is2 V/ N# j/ i7 z/ |
called prior \ref PIN_SWDIO_IN function calls.
% \8 ?) z& H! G, X4 i9 I, [7 e*/
* g/ V& \! D4 D/ k: K__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
/ m7 o5 ~3 N9 E, {" d9 X. r  `  SWDIO_Input();
% T! }. d+ J+ _5 O2 W9 K/ X; v, R}2 [5 L0 {" l+ _; v& p
* j6 A: ^$ i* F1 `6 Q$ [+ a
楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
; @: v5 O9 L; ]& S3 @. R. b' j4 a+ }即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
, j, g# ^1 n8 G4 \9 W* A
半-- 回答时间:2024-6-28 11:27:16

有人将这个工程移植到stm32f4上吗,我在网上找了一个f4的dap工程,但是编译下载后无法使用。

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版