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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。" N6 e% }, m4 o
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
6 |$ S- Z9 |; G, c5 B, m6 x( n除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

0 ?* i, r- i' D我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
% M. P% G4 G2 I7 F2 c% ]* P5 b# ~
软件复位是另外一种情况,需要向目标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:001 ~4 X6 m2 M, w  o
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

2 x0 k  `1 N/ X. G7 CnRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
! o( p. B! {0 D. f0 q& w3 n你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。, p: ^0 u. [& `9 x8 r: h7 L2 i
; Z5 F/ @7 v2 Z
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
- `3 [) X) L: X: H! x& `$ d或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
( i9 ~8 p$ p6 f- f* S& B7 w  l* C( @5 |+ r6 j( U

6 y; @+ D2 y3 [; m# ]
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
* P2 A9 y/ E+ J' I- j9 \1 n! \
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
% U7 Y0 B$ N6 X
起点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系统,轮询执行) _; h. F8 }! ?* J2 _
/**
# ~2 F; c& ^6 q' |6 r  ******************************************************************************2 |" Y( Z6 w. A
  * @file    usb_endp.c  r7 ^3 V2 q' }" K6 f6 e& }8 T
  * @author  MCD Application Team
& X! X4 d0 A2 s  * @version V4.1.0
% ]- d3 a4 Y7 p* `  U1 K1 R  * @date    26-May-2017
9 e( X, s; e7 G* C  * @brief   Endpoint routines
0 x4 ^7 s2 G" D, R9 M4 @% x  ******************************************************************************
- h/ O; _8 z7 U% ^  o( t1 k/ y  * @attention" ?& g- C" D4 Y* I. s2 e# R  V  |( {
  *
0 P9 u. F" Q$ T- C" }4 W- [  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
3 p- h$ H/ B. C. |& O; w5 y  *3 {( W1 y8 x* p, P4 y
  * Redistribution and use in source and binary forms, with or without modification,
, y* N( R# `5 j) b) ]  * are permitted provided that the following conditions are met:: D7 O* c2 r$ ~% `' `# R
  *   1. Redistributions of source code must retain the above copyright notice,: E+ {! {8 ~- z) I+ q
  *      this list of conditions and the following disclaimer.* W8 r  d/ Z9 m+ N1 f
  *   2. Redistributions in binary form must reproduce the above copyright notice,
# R4 `/ ]. V6 }& B: a2 q$ R  *      this list of conditions and the following disclaimer in the documentation" a% T! B' i, H9 U2 ]
  *      and/or other materials provided with the distribution.3 S) C, Y0 V8 \. t4 G
  *   3. Neither the name of STMicroelectronics nor the names of its contributors: ^7 n) N- G* G6 a
  *      may be used to endorse or promote products derived from this software2 C+ z  f* ~! c, Z
  *      without specific prior written permission.
5 ]2 {6 P5 W- ?7 b- ?' S  *. Q' v1 a- I3 @2 @: e( Z5 y2 P
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", W" G. V* L4 v8 c) a/ S# t9 n$ l- k
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE0 u7 P% t4 |/ z9 f9 c# g4 |' |
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE$ [& K; N" l* a: ?$ y, O, s$ w
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  [2 L8 g3 n8 D* H7 f+ D# g
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL2 C9 |+ \$ T& P8 V9 B
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR& g+ Y% P. K& T
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
" b7 g) R7 B; p" b" o, Y2 O; l  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,' B& i1 s3 C! A" q+ f4 r2 K
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE8 h! S* U2 P8 l" z2 Z9 E6 N
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6 v9 ^- l$ f: A& f+ f0 Z4 [3 A  *8 J& D8 G( M/ K( I, r" e* f
  ******************************************************************************
  c9 t) }- E# U; Q9 O( @  */
9 ?' x6 ]! h1 V+ P4 I" m' Q- [* ?2 F1 c1 R& c& J
9 Z4 |# j* |- k/ M; c
/* Includes ------------------------------------------------------------------*/
! ]" e  t% m2 }/ U4 s#include "hw_config.h"
5 C$ o2 b. S2 I5 G+ `9 o# R#include "usb_lib.h"
3 c' Z/ ~1 L: A5 K1 l, D% `: P5 ^#include "usb_istr.h"
2 C- D2 J4 k1 k+ J#include "stepper.h"- e/ ^6 e! k' g% Y$ f
#include "string.h"7 o- y" Y' ^: B- M- O
0 Z( a- E. N: \
#include "DAP_config.h"
1 X  |3 I0 r0 D$ m$ e#include "DAP.h"
; h" u: k/ X, D: W1 N$ R$ n% f# B- V- @% _% i3 t
$ x" k0 ]+ l% p! }+ n( g) U$ S4 j
/* Private typedef -----------------------------------------------------------*/
% B" P# K9 s1 H0 W0 L; T! k# ~/* Private define ------------------------------------------------------------*/
( \- E/ F/ ]% G% x" P5 r2 Y$ D; ~/* Private macro -------------------------------------------------------------*/
0 Q. n$ @3 e  Q& \& f8 {) Z$ l) l9 x/* Private variables ---------------------------------------------------------*/' M& Y/ j9 e  n; L" ]1 w
static volatile uint16_t USB_RequestIndexI;     // Request  Index In
/ x: Q9 |! d! wstatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out: t. q. S; \* S" q5 E
static volatile uint16_t USB_RequestCountI;     // Request  Count In  c7 k/ g1 s$ l& c3 B" \
static volatile uint16_t USB_RequestCountO;     // Request  Count Out5 z* d% }; W5 r! @
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
  ~+ x  ]$ H& ^6 p5 s, I
# W8 |+ `$ V3 l7 g1 _9 V1 m9 T" Gstatic volatile uint16_t USB_ResponseIndexI;    // Response Index In) r7 [6 r1 s% \1 _% k4 U6 N
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out* r3 g+ C' ]$ N- B
static volatile uint16_t USB_ResponseCountI;    // Response Count In/ t8 ?; R% i/ A1 M
static volatile uint16_t USB_ResponseCountO;    // Response Count Out
3 v% n9 ^/ o" R# s2 Istatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag& B9 }# R  A" F6 i) U2 H7 ]
static volatile uint32_t USB_EventFlags;
9 i# R) U7 ]& u+ w4 Z
% W8 s! {" V3 ^' J0 {$ bstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer6 w- k% g$ g  \) q5 M+ @  R
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
. F/ m# \8 _4 Estatic uint16_t USB_RespSize[DAP_PACKET_COUNT];2 D: W9 V( B0 k$ r) B$ z4 R
' P. G3 h1 ]9 e' U; Y- q, g" R
/* Private function prototypes -----------------------------------------------*/
5 h8 I3 _7 H3 d7 a0 ?3 F( Q% ?/* Private functions ---------------------------------------------------------*/# R& g* \5 ~5 n+ F
/*******************************************************************************
; [! ~* i6 z' A! ]: I* Function Name  : EP1_OUT_Callback.8 m/ k! p1 i* T& H0 V+ v
* Description    : EP1 OUT Callback Routine.
; e& w. d: C; v* K# c  f: x( g+ I* Input          : None.$ p9 x) D, ]! s! o: ^" H. X" J
* Output         : None.
: I( {# M# F: @. }$ q* Return         : None.# `2 V, `' Y: u2 d4 u- D
*******************************************************************************/
4 T* G: `; ]- @void EP1_OUT_Callback(void)
9 p) y4 F8 b* I$ s& J& g* B- {{
# F3 o& p0 c- r# A; I: C        uint16_t n;; `( t2 l% b" h1 h$ [: N  z6 |

  v. K( ?/ R, j" Y        n = GetEPRxCount(ENDP1);* O1 s& t% R& v. \  {
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);; b6 b4 l4 n. u8 T% Y: y
        if(n !=0){
# R; y' f7 K0 n1 n                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {% i5 B5 h. W9 c/ d% Y
                        DAP_TransferAbort = 1U;
) \7 N' t" Q, ~" f; ^                } else {
' v6 H+ M; M- s8 M* D                        USB_RequestIndexI++;* a6 ?' ~, m5 C7 A/ R$ h+ n
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
8 M. C- `+ t5 v- S& s                                USB_RequestIndexI = 0U;% a! n  V8 H. \, B, T% x
      }* Y6 o. ^1 f. L5 S' \4 n: }
      USB_RequestCountI++;2 R+ N7 a  b/ ]+ D  W4 T7 N
        USB_EventFlags = 0x01;' K  o' y& z, X# ^* U; J4 Q
    }8 K5 V1 [5 {! p& D
        }        
; ?0 ~, |: |5 o$ X" k- ^+ g        // Start reception of next request packet# V! }% Q( s, Q6 q
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
4 {3 F7 i; f+ l# o, K8 F                SetEPRxStatus(ENDP1, EP_RX_VALID);
4 M" x, w9 N6 ?: I' a        } else {& N6 d5 e" V! f' ]; [. K
                USB_RequestIdle = 1U;& G7 k* J4 G0 s7 B- I8 }
        }                        2 W( _' z, X- y( Q" Q8 T5 Y, z
}. d2 F9 f: ]* B4 K# v  h' Y

  T: F, A% @2 R/ N, O, m5 y  Z/*******************************************************************************
: ]/ u5 f) u) D* ^5 K* Function Name  : EP2_OUT_Callback.4 ^5 v4 F7 |1 i( v) d
* Description    : EP2 OUT Callback Routine.
3 M" R, |* w- E! z1 O* Input          : None.
2 @2 |; _- y; J7 v* Output         : None.1 X1 `3 r7 n" S  C: v
* Return         : None.; F- A% C9 _0 b( h! A7 f
*******************************************************************************/
+ @# w9 y+ |8 y/ a" T6 jstatic volatile uint32_t TX_n;
. K3 z; a' k8 l0 X4 _' y  Bstatic uint8_t *pbuf;7 s! p! R& k: q
void EP2_IN_Callback(void)
' D1 [  {9 t6 d3 c1 q0 o{
1 C- r5 m4 ]& z6 h! J        uint32_t a;
4 f* `3 T/ I' q8 M. f' r7 L" F        if(TX_n>0){: X8 C8 O: _( f9 [" U
                pbuf+=64;
* }0 g8 x( p6 s0 Q6 U% f. m                if(TX_n>64){) o. G) z7 k- ~& j  c- r" T2 m
                        a=64;
  Q9 x/ b3 p; B- F) t                        TX_n-=64;
* \4 I" R7 N4 p                        
; ]. x# h/ F6 Y8 P% d) m( d                }else{
3 L! b( j( R% `- w$ ^1 b0 @                        a=TX_n;
0 r+ b5 p6 c, j2 Q5 E                        TX_n=0;
1 r( b) t0 g/ G! {! }' G+ x                }
! V: J; z- i* G5 u1 `! e% s' O# u                4 E: ?* y' l/ v' k5 W# m
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);* }* L7 S' G* u- @
        SetEPTxCount(ENDP2,a);3 e2 I7 t  ], t+ J2 H' d7 p1 ?
                5 w/ n' X6 R+ L; K8 [0 ?" a
        SetEPTxValid(ENDP2);
/ }6 d' I" u1 M        }else{
6 j# F$ q) g) f  M                #if (SWO_STREAM != 0)
3 X" k5 c- x4 e* _4 F$ u4 [                SWO_TransferComplete();
0 K# }7 O! Y( e  D1 u8 H4 W                #endif
9 f( G1 P2 c- H( J6 m: _        }
) ^/ Y  u( a$ Y$ o% v1 ?4 ]$ R}7 D" j# W3 d* N
" J" Y, |* R' H* R2 |6 X/ h9 }
/*******************************************************************************
+ Q' Z  X/ C! {5 p- f' d* Function Name  : EP1_IN_Callback.: ^! {) O& Z) u7 ^3 T! D
* Description    : EP1 IN Callback Routine.! e9 ~7 B- l4 \. o& Q
* Input          : None.
+ [! ]# G# e) N$ |& D0 ^* Output         : None.
* W: h5 j0 y3 w; X) P) v! o! P* Return         : None." j+ C( O3 k+ O6 `
*******************************************************************************/
* d' _- R9 k" V7 {2 j+ {! }* Qvoid EP1_IN_Callback(void)
( e! I* R: d+ e9 F  v* `& X{
( r4 D% c. H- R% t    if (USB_ResponseCountI != USB_ResponseCountO) {
  k( ~% x8 p5 S: d4 n! T      // Load data from response buffer to be sent back2 q2 W) N/ J9 n- N5 S& f
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
1 n6 u. O* M; {& E6 }+ u% q                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);2 H* K: z. v3 E2 k. g+ r+ q/ g
                        SetEPTxValid(ENDP1);                        6 t0 I( _* l: m" n  W& V
      USB_ResponseIndexO++;
  g3 {6 G8 K1 P3 [+ x# z      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
! F9 J: b; u' R        USB_ResponseIndexO = 0U;
1 d; L, e, u; z/ s8 e4 m. G& I      }+ K( T2 f& c7 w/ L# W& H' e) Y
      USB_ResponseCountO++;
. \* x& P( f# I. k    } else {) Q' H0 R0 o  `
      USB_ResponseIdle = 1U;
" {, L- G$ `% ?% F8 ~5 C    }  
0 y& a1 w9 S& Z, B  O! u" j. {+ Z}1 w( }& @' i( Q" U# I. o
, l. v1 D. @) q& R  Q# i$ B
// Called during USBD_Initialize to initialize the USB HID class instance.
4 U$ W! n+ i0 K& @void DAP_FIFO_Init(void)
! c$ g' ?7 }- s% i{
  }6 S% a  V9 u    // Initialize variables# Z$ P$ v8 w. o7 O+ x& q
    USB_RequestIndexI  = 0U;
& u0 R+ u0 x8 n' R, J    USB_RequestIndexO  = 0U;
/ E/ W: u* m6 y5 S/ ^    USB_RequestCountI  = 0U;# Z" V* C3 r; Q0 t$ W; x
    USB_RequestCountO  = 0U;; X9 D  X! n; V: |; d; u, y6 L
    USB_ResponseIndexI = 0U;; u: O" A) N, b- I" \) J( ^
    USB_ResponseIndexO = 0U;$ d5 {* Q; g/ _! F; n8 J( C
    USB_ResponseCountI = 0U;& H1 L1 U3 C( W2 `+ b
    USB_ResponseCountO = 0U;$ L) s8 n, {8 y
    USB_ResponseIdle   = 1U;9 K& c" I) U* n$ g  \$ G6 X
    USB_EventFlags     = 0U;
- z2 O$ P1 l4 `( b* S* [}7 x5 w" E' p% y& C
6 f# l/ e' X6 X, X7 i
uint8_t DAP_Thread (void) {6 q" |& L3 G8 n7 ^8 y
  uint32_t flags;
& S" |& _, {' g" l3 ]: Y$ _  uint32_t n;. r" R! G2 l! r

) @. y" C7 j' z) r* z" y7 c: N  //for (;;) {
& o- Y3 L* c; e  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);% M/ Y9 w6 M3 L/ i4 Z) d& n5 c& X
                if((USB_EventFlags & 0x81) == 0)& l4 B, x/ e/ h" C7 F; H
                {+ v- l1 C6 H/ m' ^
                        return 0;
# ~/ i% r, ?# T( O* B" o+ K9 o                }
! T' U0 x5 D+ i% e/ x( u                USB_EventFlags &= (~0X81);
' w& _' d5 i# e                - T- Z; z1 j; b2 `7 i; f& y  ?
                                        0 j) z; M. E# I+ z6 z* l& z2 \
    // Process pending requests, G3 k1 w% L) G2 H  I8 A& J
    while (USB_RequestCountI != USB_RequestCountO) {
# F- c  W( d9 ?  x0 G8 d                //if (USB_RequestCountI != USB_RequestCountO) {
5 ~/ n) z4 M- r0 X& G6 f8 r, O  ?      // Handle Queue Commands
% ]) f+ y- n. Y/ f% n6 @# t      n = USB_RequestIndexO;
0 }! l8 Q5 o; m/ e+ E' {, `      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
; X/ U7 u8 o. R8 |+ R+ _                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {% V, f" h6 @  B+ @
        USB_Request[n][0] = ID_DAP_ExecuteCommands;+ x1 [, I7 G, |0 K1 e! g0 h1 D, b! B
        n++;
: W; h' a- L) X        if (n == DAP_PACKET_COUNT) {
: ]* u$ k- q( g9 v% k% w5 q          n = 0U;7 a( {! K$ h' U; H" l/ I& t
        }5 Z4 L: j$ c7 ~7 m% d2 y
        if (n == USB_RequestIndexI) {2 J! T( ?- _4 m& k* ~0 ?
          flags = USB_EventFlags;
: u' D- ]9 T; Y8 S7 v. [) N          if (flags & 0x80U) {5 ^# Q; A1 i' \* S2 B  `
            break;) g/ M$ O& z" e
          }
' @( G5 s+ N5 R4 Z        }+ A1 n0 @% [* S- h! t# v7 U& V
      }
! n3 A! o9 A! g2 V# z, k+ R
& g* a3 X: h8 k/ Z# z* E" r      // Execute DAP Command (process request and prepare response)
8 a/ m# K3 i- h      USB_RespSize[USB_ResponseIndexI] =
) S, h, \" t; L  T% \* a! a; |6 {        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
& B' ?. Z+ g9 O8 o
, l+ S7 n) g6 X8 @3 f2 v' h      // Update Request Index and Count( h$ ?) T8 O0 Y, w. ]! S. u
      USB_RequestIndexO++;
2 N9 o' B2 e& n3 X" H  Z% ]      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
$ |& g: `) J" l2 S, ^        USB_RequestIndexO = 0U;& }, e! X( I3 b; W! G. C
      }
3 U& v8 \# o/ z& O; y! y! Z      USB_RequestCountO++;& s& }3 U: [. e- k3 I/ j; V

% E7 i7 |* F4 U0 E4 y. V& m      if (USB_RequestIdle) {
8 l. a2 |3 b' o0 D* D$ y' o        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {8 e# O/ i7 P4 S/ n, I. p
          USB_RequestIdle = 0U;
6 Q& [7 C9 P: j& j& t  D/ ~+ u          SetEPRxStatus(ENDP1, EP_RX_VALID);6 v  V. j  T5 @& X& }
        }$ ~; R7 K/ k$ R
      }
; U, D6 x3 I& {$ n2 `: P, w6 S5 @' _+ L6 m
      // Update Response Index and Count
- D" z) b, p" M& s+ M      USB_ResponseIndexI++;* L0 F7 g" ?2 M% p
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {' n/ }$ E" E* `, g6 ~1 x
        USB_ResponseIndexI = 0U;
# q/ {9 Q( v6 \  ^      }* b- T# K4 n2 c; R' |/ I( ?
      USB_ResponseCountI++;
' [) Q2 C. X8 u: L7 u# d
6 E5 e. \: w9 n7 _6 u8 c" \      if (USB_ResponseIdle) {
. L% K/ Y' E/ n2 t; I! L        if (USB_ResponseCountI != USB_ResponseCountO) {
; c; \2 }& V( J! r5 l$ K! q          // Load data from response buffer to be sent back
: p8 i, S4 k& X; m; r4 F4 z$ s5 i          n = USB_ResponseIndexO++;
! c9 ^3 f; S1 A+ Q! L          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
; v  `. n6 S' ^/ T. W! X- u            USB_ResponseIndexO = 0U;
+ ^% F- M$ y$ g# h5 z6 o- g( O3 o          }( c$ p- y9 D5 f- {6 k0 ~7 f
          USB_ResponseCountO++;5 Z, ^7 h5 c7 f7 l" ^
          USB_ResponseIdle = 0U;' |1 j/ L6 t7 x5 @% D
          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
! N9 C0 ?  m0 X7 y6 P/ J5 ]                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);- x# Y; @: {7 o. H# X
                                        SetEPTxCount(ENDP1,USB_RespSize[n]);$ X* h3 |4 n. Z( ]$ g: q8 y
                                        SetEPTxValid(ENDP1);
( i, H& p9 Y7 w) o( H  j# y  c        }
! v8 J. F4 w( W- e! H$ f! R; T      }
9 m/ k, |( y- F  i    }
; B/ O+ ^' O+ G$ ]" ?        return 0;
, z) n, v. l8 R6 l) L$ U}; w% g, J- @; v1 a3 n+ p

- H' K0 w, M  }; O// SWO Data Queue Transfer0 }$ ^# g4 ~7 {7 j7 q4 j
//   buf:    pointer to buffer with data) ?. M( ?' ?* k( G* V7 F
//   num:    number of bytes to transfer
1 U# t  o7 _  c" J6 yvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {2 r$ t+ i" s& p! y$ q7 r
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);6 L  r7 B* ]1 ^3 \
        uint32_t a;! a& e. @2 q/ d$ Z  I
        
& y+ c( A+ i  b# b9 F        if(num>64)
* A! d( h  z+ s% w2 a3 M        {
. `* A2 @$ h8 J; n                a=64;
: [( r9 C% L8 a$ l" ]/ r                TX_n=num-64;% ]8 w) r# I9 t0 P
                pbuf=buf;
8 C0 ]) o, B9 m0 w$ g; ^2 P" a$ T9 e' F0 S8 G. L# F- |+ f2 O- Q: t0 d- o
        }else {: V5 y- @/ G1 U  A
                a=num;- F) X# `1 D( D; w! A
                TX_n=0;5 B  k+ h: m' d1 [* _; Q
        }
5 [8 _  y# @4 x1 s. d) u6 e. T        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);  ?9 k* h; j# N4 K# ?8 q3 v
        SetEPTxCount(ENDP2,a);
2 O6 k1 @3 a4 l7 x% i* j6 l        SetEPTxValid(ENDP2);! {7 Z2 T; M  h7 U$ P3 [
}
& Y' H$ B9 V* U. Q$ g5 g) ^) D/ H5 ^! @0 d# v. [9 z" v2 e; T
// SWO Data Abort Transfer
3 i1 h! V0 r' l; N% `void SWO_AbortTransfer (void) {
  Q5 J. F: z/ R4 M  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
# f8 w/ M; g" j2 w7 h        //SetEPTxStatus(ENDP2, EP_TX_NAK);; Q' L) [, F0 r. W& y! {
        SetEPTxStatus(ENDP2, EP_TX_DIS);
& z: Y) }! G- {3 c; d) {        SetEPTxCount(ENDP2,0);7 \( ]' M; W  _' }
        //TX_n=0;
! z* L4 H5 I- a. A}
* o1 v5 x$ s" X& l5 o  B1 y, f/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
! `9 [; K, b- N# X& {0 V6 L  m( S0 G* R; _8 d
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
7 W# R3 |- A9 F+ [( M0 F) eDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了
  P& A0 C4 J  Z9 F$ m__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
1 S* x2 s) B. p+ R2 S: }9 s  return (DWT->CYCCNT);, \* E( w2 R) S  d
}
  X, Y- i- h0 Z- O2 S
4 g; u  Z1 N6 y3 P/ u+ cvoid DWT_Init(void)
4 q0 q  j) a# x4 r# e1 I{' D6 e$ c, g* I5 B6 ^" M$ z' R
    /* 使能DWT外设 */% w3 k$ Y# V" w! f; w- R$ U
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
. L  A% B4 c# [7 _# Q7 k/ _" Q; N! d! v2 O* h, @6 H3 G+ h
    /* DWT CYCCNT寄存器计数清0 */6 U+ g5 Z2 V' S+ T& R  D( D& }
    DWT->CYCCNT = (uint32_t)0u;; a- y4 J& h& ~) s

4 j' L- A  L1 ]- b    /* 使能Cortex-M DWT CYCCNT寄存器 */
1 @/ y+ I  B7 W9 }    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
: t$ ]' h- R4 y* ^# I}" G  M4 Q# F+ Q0 P+ q2 U
        8 E/ h+ N5 h6 R

* G- l% [/ W& Q. e2 R# I然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
2 l6 S- O+ |0 |2 |
" l* p1 B, o' G然后改为使用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不香么?
% n! X) F4 [, w$ [8 E声明这个变量static volatile uint32_t SWO_EventFlags=0;" s% v, ~- l* R- ^" ]" s1 ]* \6 L, G
在SWO里每一处调用osThreadFlagsSet的地方都改为如:- A6 f2 U: i, p$ h) J; |& t
//osThreadFlagsSet(SWO_ThreadId, 1U);
# I2 ^/ I9 O' }. Y4 a! S1 bSWO_EventFlags = 1U;- M: P2 w" T$ O5 L6 f

9 n7 {' L4 S) O  ?% U4 N; S4 p  p0 K7 g  C% @- G
// SWO Thread8 [) d) V5 z# w5 F8 y( A
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {) w% x, B4 ?# N. W- b/ C
  //uint32_t timeout;
! K5 }1 r/ ?; E" v' i# g' E1 p  uint32_t flags;3 m8 X% v2 ]% _9 M$ l4 W! I- [
  uint32_t count;1 B- V7 G- c3 d3 W8 E
  uint32_t index;& l9 v/ }8 F* X: a7 f
  uint32_t i, n;
8 p* i! {% k4 C2 _! j7 x  //(void)   argument;
/ j; j8 n, O# L3 H4 [
2 |' j& m% l3 O' v9 R' h  //timeout = osWaitForever;. Q/ v6 Q" g" s: r8 r  z2 d
3 T4 f9 t/ J# q- l" r* P
  //for (;;) {) z6 U' g1 X& W$ O$ v: L$ C
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
  Z: V# Q- n: K: G- {! x                if((SWO_EventFlags & 0x01)==0)return 0;7 J( B. z2 l3 E- E* `
         2 h! y! g  b* R9 z
                flags = SWO_EventFlags;0 n8 s% w# g" B7 Y" w
                SWO_EventFlags = 0U;
8 u+ P4 R* g! U    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {# j5 Q1 y" [% j1 \% A# j- R# Z
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子& l2 k4 A( E8 A  G& m  r: Q+ j
                        ;5 N( ]- \6 a+ S' d: a" m
    } else {
$ J' X8 y7 Z; v; o0 L5 _; X2 Q0 A) s      //timeout = osWaitForever;+ P! y6 t" g2 v) t; I% x  x( x6 a2 F
      flags   = osFlagsErrorTimeout;1 [3 l+ g6 |+ @  h% Y" ^9 Y9 o
    }: Z- B2 Y/ Z# K& _
    if (TransferBusy == 0U) {  n1 u' K- |% O# L
      count = GetTraceCount();
# w! K; U7 w4 {+ L3 W1 N# E: H      if (count != 0U) {0 J9 g/ _( C1 k
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
  Q; l2 u7 c: s        n = SWO_BUFFER_SIZE - index;+ \5 L; ?4 {+ \/ n- ^
        if (count > n) {
- C) M+ c0 `( @; S: g          count = n;9 [* D: {4 h8 A* S& m- ~: h) v
                                       
) D2 ^3 e. t; n        }
6 V; G) ?9 t9 b( v+ S+ `                                if(count>USB_BLOCK_SIZE)
3 m; p) [% o) x' {                                        count=USB_BLOCK_SIZE;$ p3 d( A- ?# W5 o1 j! N3 f
        if (flags != osFlagsErrorTimeout) {
( e" N7 V1 s9 p8 J1 g: Z          i = index & (USB_BLOCK_SIZE - 1U);* W5 W1 s) D: z8 [% t9 l
          if (i == 0U) {/ D- K) c! G3 }# _
            count &= ~(USB_BLOCK_SIZE - 1U);
! {$ Q5 \9 k, {0 v; @7 ^2 B          } else {
& u4 v: p) c6 u( L# x            n = USB_BLOCK_SIZE - i;: d4 ^& Z& s1 Z' ]8 d% l
            if (count >= n) {2 w# q) U; [; N. f% h) Y1 b- h
              count = n;
2 H& ^" J6 Y9 X9 P            } else {
( z9 {7 N4 X% R1 d) x              count = 0U;
, j* m( m- C" H( c( n            }
# p1 R. e) ?# y# _          }9 i% U/ g. g9 @% k  ~9 {' A7 D4 ~
        }
+ }2 _1 r# {* b) s! D0 E- L        if (count != 0U) {
7 K9 Y  b  t1 x3 z) [  X' |          TransferSize = count;
- t/ \. X( n- e) R( U9 q6 z8 s  q          TransferBusy = 1U;/ V% s" ?+ W- f" O, z1 B
          SWO_QueueTransfer(&TraceBuf[index], count);8 D' E3 c+ m- A- p& N4 C0 u# c0 j2 H! p
        }
1 E7 N$ f2 O+ a) P3 R, C, x, k- F4 V      }3 f- z) ]# j) y+ ?
    }
, g/ m9 D3 ~- ^/ t4 a4 p' q& m$ Y  //}& z+ w6 c, w/ F
                return 0;3 ~5 O! V4 _( ?& [  L# F
}
9 p4 w( X1 a( ~+ ?6 C利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.- W& P  Z6 w0 v* E
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).' }  G/ p: _+ d1 C
static volatile uint32_t SWO_EventFlags=0;; S- z# I  G2 S6 V% t) @+ G, w% I. `
static volatile uint32_t timeout=osWaitForever;5 z; e# h( r2 G2 \3 D% D
static volatile uint32_t timeWait;
3 F' d8 n% J/ l/ z3 Q2 e5 a( F8 S函数改为这样+ X- Q8 ^0 |5 C6 t3 U$ }
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {1 x4 p( \/ N7 S, E
  //uint32_t timeout;
( z- e  x% u# q" J  uint32_t flags;
9 p5 X0 {2 [% R  r( e  uint32_t count;! P2 ]' D( O! r$ O0 R# }+ w
  uint32_t index;
3 Z% q6 u" B9 u7 p* [+ N  uint32_t i, n;
7 X2 ]' m3 w7 v2 T+ \* u+ p" ^; X  //(void)   argument;: t1 D' K7 ^7 ~; |/ L4 t+ x
2 G9 z  z1 v% \- v1 ~) v5 o
  //timeout = osWaitForever;
- v. W" u1 R/ J9 i  _8 N$ O5 N7 w$ \9 m) i, n* W
  //for (;;) {
* _2 T1 x4 b* l& P    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);! U3 O- m1 ]: O: _( n* b2 T
                if((SWO_EventFlags & 0x01)==0)6 U4 _  y7 P: E3 B" P
                {
$ q. K7 t) ?" y/ \3 f1 x                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了# Z: K9 P1 r# P6 h7 @( p5 c
                        return 0;- w" d. G8 w9 M! p0 w, _
                        
. g. A* g" ?7 t8 M/ l* ?                }' E. ^2 X. `/ u% P( d
         7 f! I- I* n6 v' B
                flags = SWO_EventFlags;
; y) x/ i8 \1 A, _$ J: u                SWO_EventFlags = 0U; 2 D/ c  K6 l4 ?, H6 |
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {* B9 O! _) u4 ^
      timeout = SWO_STREAM_TIMEOUT;
; w; g6 i: Q  m0 e' i      timeWait=DWT->CYCCNT;* ?- u# ^6 l0 o" q2 A& Z
    } else {, r$ u! |3 L0 J% @
      timeout = osWaitForever;
; B% I/ c" e- z& A/ f8 z      flags   = osFlagsErrorTimeout;
. s' n9 t# Z) L    }: C# H! ]: N3 U4 O5 v* ~
    if (TransferBusy == 0U) {
, J3 A% q8 X2 _' _! J5 s      count = GetTraceCount();
) ^' D* X) n. ^) q" X9 _8 B      if (count != 0U) {  a5 z8 T3 [# W" k
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
3 Q6 Z) \2 i: C        n = SWO_BUFFER_SIZE - index;5 l, _1 ^; Q3 N; O  s1 z
        if (count > n) {
6 }/ F/ e! K, t- K6 ]$ f* {          count = n;5 U4 a* J3 S+ V7 w
                                       
9 C2 q4 ]4 ]% n/ b& T; j        }6 ]+ \# U. r( Z3 Q7 T3 [
                                if(count>USB_BLOCK_SIZE). c/ Z$ C& p; J* G$ w, `% x5 a- q
                                        count=USB_BLOCK_SIZE;
" V" f1 W' B2 V' L6 n9 {6 @        if (flags != osFlagsErrorTimeout) {
' @' [; F, \9 U$ K% G7 m' E; }0 v          i = index & (USB_BLOCK_SIZE - 1U);
/ i8 [6 S" C. @2 R' O( X2 _( W& b3 F          if (i == 0U) {3 w/ ^2 c2 u% [! D1 o' h" Q
            count &= ~(USB_BLOCK_SIZE - 1U);- R- M' l; m$ r/ g2 c8 p! m
          } else {
" I9 p# l! @0 p# c            n = USB_BLOCK_SIZE - i;
% ]# ?0 ~5 ]+ h' W" M& F            if (count >= n) {
, |$ Y! s' s' K0 i* Q' \; b              count = n;
% q5 E7 U! H, X' G            } else {
3 N% G; Q& V' Z1 N, ]3 [' R              count = 0U;
( {: H5 M, H$ ?/ s9 ]% m            }6 p' ?0 ^9 Y& y; Q
          }
; [/ o# e* f8 f4 I        }
$ h. N, b! I/ Z5 L( C+ p  B        if (count != 0U) {
- N5 I7 }0 P( |: i* p: A+ Q6 w          TransferSize = count;
& U7 _/ T: B; t2 G/ \: X          TransferBusy = 1U;
# C0 g8 ^+ m" Y+ s( \% E7 B+ q          SWO_QueueTransfer(&TraceBuf[index], count);
; g% h* p, ]+ ?; {        }' O1 P4 z  K, W. B$ i
      }
, W: X2 u, F" n* U    }% h8 K& k2 w1 q
  //}, c1 M, ~. k5 ], P- d6 X/ @
                return 0;
' E* ^1 {  h8 ?2 h1 ^2 V, F}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了4 a2 u/ n3 n; O' v  j

1 ]8 j- y) n6 l: ^. {0 m* ^& @! RCDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率( R7 Z% }% `. Y) x3 p9 [& b4 i$ n
+ c. j0 Z; _0 Z
$ w8 q% a' d8 I
int main(void); k8 ?1 W+ d5 y% l$ A6 U
{) j7 m/ Z0 R( g$ z7 t1 l% M
  DWT_Init();
6 @% d3 ]6 y$ \" o        DAP_Setup();: v8 Q. V* R2 ^9 O% a/ E
  USB_Interrupts_Config();
3 t' b% B' B! T: c  Set_USBClock();
5 K5 t& m! S- ~1 B  USB_Init();1 m* C, E7 Y7 R$ U$ \
        //TIM3_Init(35999,0);- @, ^1 P, [+ q$ m5 C! T3 T' `3 q/ n
        //TIM_Cmd(TIM3,ENABLE);$ ?8 Z: d% }; m6 f
        / r' s7 l6 O9 o
        
5 P- T1 O, M# l7 L2 Z% A) H  while (1)3 W: U" q) v0 N4 `- x
  {
' o% a' U5 m" _: a                DAP_Thread();
+ i7 Z* i5 Z8 B" V4 s                #if (SWO_STREAM != 0)
6 h1 X% f. R5 l) T, S9 u$ ^                SWO_Thread();
) C5 v' Q1 N) q" T# q                #endif
' Q7 z+ F: |+ j$ T  }
! v1 R& L+ ^' S. q}
* F+ a0 r3 L5 R# }$ K2 y1 X* I2 c2 l9 [' _5 O3 j- M
对于DAP_config.h的IO配置我是这样弄的: X+ A% `( I4 Z! Y; d! \1 |  d% N) X
///@}3 h6 t: g- S2 ~) u
// Debug Port I/O Pins! N8 d5 ]: @) w; O* B

  P2 Y6 s5 c6 D+ X! N- W, N: h// SWCLK/TCK Pin                GPIOA[6]
# ~0 O5 _9 |( o# T; N/ Z1 ?! m% g# z#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
) s2 p* n; X+ X0 i" @1 M#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
- Q( ?  S8 b/ H4 g* z  u0 G4 z; q( {  `; _
// SWDIO/TMS Pin                GPIOA[7], c+ [; y7 c7 e" w  Z* ^
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
# @2 n# h; Z# Y, y  F. f#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C# {% ~, T! g1 P$ {  a4 p

) Y$ _$ h, e% Y/ Q8 @// SWDIO Output Enable Pin      GPIOA[7]
! G* \% c* {' p) L+ o& O#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
: }" p! A; ]" l7 ^+ |1 r- _                                                                                                                                *(uint32_t*)0x42210070 = 1; \
/ m7 c4 t5 |; @% r                                                                                                                                *(uint32_t*)0x42210074 = 1; \
1 m2 Q& C& H- o6 O& }& J- g3 u                                                                                                                                *(uint32_t*)0x42210078 = 0; \
, p: }9 ^3 A) U, k; G                                                                                                                                *(uint32_t*)0x4221007C = 0;}0 }# Y  p7 I; `! _( l( x
8 W  A4 F& G) i& \
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
9 F! B+ Y8 L  |6 q) a                                                                                                                                *(uint32_t*)0x42210070 = 0; \+ ]# ^  V2 Z. z( Y# l3 K% c0 v' x8 E
                                                                                                                                *(uint32_t*)0x42210074 = 0; \
* `1 W4 [, L. ~1 k. U/ ]                                                                                                                                *(uint32_t*)0x42210078 = 0; \5 D6 U$ l# U# n6 q$ m7 h5 L
                                                                                                                                *(uint32_t*)0x4221007C = 1; }! T0 P0 z! @/ C2 a( ]8 k
, g1 b$ d4 h3 h8 H4 x. \) S5 ^
// TDI Pin                      GPIOA[8]- c" G5 x1 t- d' |# t' f
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A02 p0 N/ A% p9 E
#define TDI_IN                                     *(volatile uint32_t*)0x42210120( H. L& c, B8 F& P, a" F% l( U: @$ [
. {$ q: l! O: G  k& i% P
// TDO Pin                      GPIOA[10]( m3 D) y. I: A/ F3 z) d
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8. ]1 J* T) ^; x% E
#define TDO_IN                                     *(volatile uint32_t*)0x42210128
( R4 [& g$ d  J0 N6 x* x% ?9 X* L
6 s* s  |6 a. U$ P4 A2 R: x// nTRST Pin                    GPIOB[3]! E! S; l+ i/ X/ v1 ^
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
1 a* J' G, {/ ?3 R#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C( ~4 \. Y6 h0 I, a. ]
- N5 s/ C" W8 E) N0 s3 W9 Q
// nRESET Pin                   GPIOB[4]
2 m; q; I1 i/ {+ L/ o, ]$ c' L6 j  g#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
% S, j0 h4 F" {/ h& I#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
* C; H5 V0 U7 o; S
% P2 b6 Y) Z/ L4 E9 w5 X2 |% h- Q, ~// nRESET Output Enable Pin     GPIOB[4]) ?& B' H6 g/ e" U( \
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \" |$ q" T, L* S+ p5 E
                                                                                                                                *(uint32_t*)0x42218040 = 1; \" B8 ^6 S' g. y( ^: f5 Y% h. q& B
                                                                                                                                *(uint32_t*)0x42218044 = 1; \* s* C' @, X6 E0 s: @( e; z$ V2 Q2 V
                                                                                                                                *(uint32_t*)0x42218048 = 0; \
8 E4 @6 p; T0 g/ d+ x2 A. M" f) e                                                                                                                                *(uint32_t*)0x4221804C = 0; } 4 a, g6 s# e. n! `3 w! i

3 E: G- n! z* Z#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
3 ^" c+ I- f& z1 D: y6 H                                                                                                                                *(uint32_t*)0x42218040 = 0; \3 S8 e: `- h) H( i7 ]) x, p
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
8 A2 Q8 O# s) R; l                                                                                                                                *(uint32_t*)0x42218048 = 0;\9 B% g9 l! e2 W
                                                                                                                                *(uint32_t*)0x4221804C = 1; }
) L- ~; h2 {4 ]  V, }9 n7 ^7 P( |1 q( |7 c+ N* B# V

/ s3 b8 N+ @) \0 d( z// Debug Unit LEDs! ~6 P3 C, G0 P
3 Q9 o7 U/ n; r
// Connected LED                GPIOC[13]1 |  J, U6 e  Q2 C" o
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4( S2 d6 S0 B% d$ |3 a
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
! L! B) e1 F' I9 \  A* I- |' p, |+ l6 s4 z: ^( }
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
9 X6 G# Y2 l1 }                                                                                                                                *(uint32_t*)0x422200D0 = 0; \* h% ?0 S+ B# ~, u% f
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \3 g0 W" b  e5 ~) l: k- C, ~+ T
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
2 ], T# p: u4 V3 w                                                                                                                                *(uint32_t*)0x422200DC = 1; }6 |: b. Q# Y( S' Q/ m' |" z
// Target Running LED           Not available0 Y6 r& Z. A0 |$ f# X7 b

* O% n# N. G" q" L4 }1 \: a0 W9 W// SWCLK/TCK I/O pin -------------------------------------( o! p2 n$ c) Z& ]
. I* |1 V4 P% ], f
/** SWCLK/TCK I/O pin: Get Input.
4 h- e' v/ X/ d2 t# |\return Current status of the SWCLK/TCK DAP hardware I/O pin.: P0 J* S/ P; r, N8 F" U
*/- ^. L/ Z4 k) @8 X3 h/ D
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
4 L0 N' b0 m1 h  return (SWCLK_TCK_IN);
4 g8 U1 @) A& d; i1 w}
- e% h1 A* z/ L) Y9 M: V" e' E6 N8 z
/** SWCLK/TCK I/O pin: Set Output to High.
, E) s' Y8 C- K) z* h0 S) |Set the SWCLK/TCK DAP hardware I/O pin to high level./ c2 H3 Z9 s  @. Z& f. {( V# `
*/; z* }4 i2 S! \; _
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {2 ]7 Q8 Y5 Q; y
  SWCLK_TCK_OUT = 1;0 R! a* B# E4 u, T2 h. K
}
0 f2 S: a. y4 y, h4 x5 U3 e8 x- r  R+ V/ T& A& n' [* ?
/** SWCLK/TCK I/O pin: Set Output to Low.0 o- z! ?# Z" o, t
Set the SWCLK/TCK DAP hardware I/O pin to low level.
* ^, V& Q% {+ u% Y8 \% |*/* p6 R3 w* I( p7 [( B( ^
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {& l0 f$ t& ]% l, W
  SWCLK_TCK_OUT = 0;
. v7 R- q" N- x) N# e+ u% _}
' S) i' y* m8 v/ r5 a) \+ I) o
( F5 O  _; h: }/ n& _# m, V& K* J* w! t% }
// SWDIO/TMS Pin I/O --------------------------------------
' W' |$ u5 v; q! m: c
  N( E) w" t- ]& N/** SWDIO/TMS I/O pin: Get Input.6 x' P6 E+ F" R7 h) g4 w  c
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
% D& q, b# v3 f' P; ?& b! e0 L*/9 B7 ]2 u  L7 ^, o9 i
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {7 R0 F& J$ a9 V6 M% z0 h
  return (SWDIO_TMS_IN);7 S) R5 l  r8 i+ @7 O2 O
}
! i1 V6 }6 T2 U+ x- ]: }9 X9 ~% Y- d) M$ {0 D; A, W3 W
/** SWDIO/TMS I/O pin: Set Output to High." n9 k! u# b) i0 f) H0 M  {6 g
Set the SWDIO/TMS DAP hardware I/O pin to high level.
) C( r6 u  n' c! A*/6 K  N1 S: j) s2 R1 @* S
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {4 ~2 r7 y1 G) f. K
  SWDIO_TMS_OUT = 1;
9 t5 Q, x; S0 R" X! S6 ]}
1 B, _; v8 M+ `  a' M0 V; H3 s# T) d8 `% Z7 ?: r2 T5 F  W: W
/** SWDIO/TMS I/O pin: Set Output to Low.# z9 n4 ]0 z0 K5 Z6 z( z
Set the SWDIO/TMS DAP hardware I/O pin to low level.5 b5 ]$ |# U' q1 F9 W5 Z4 ?5 H" {' @$ W+ i
*// @/ U6 m( f' M9 g( d3 @0 Y0 z. c
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {2 r0 W5 }0 U# F5 |  T8 x
  SWDIO_TMS_OUT = 0;! x$ E8 R( I  a8 i7 C; e* A
}) V4 Q$ f3 y+ B* ]" s: R; a

4 {0 K4 v' ~% x3 r! B/ ^  U/** SWDIO I/O pin: Get Input (used in SWD mode only).
6 K- ]$ P* z3 z$ l9 _0 l( h\return Current status of the SWDIO DAP hardware I/O pin.* f) ?7 {8 f% {
*/3 _: ^5 n7 z& J% L
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {! ^+ v' i- {5 b" b
  return (SWDIO_TMS_IN);
, A6 E# v( G+ [( T1 F, n}7 i. T" ?) y8 q/ Y; g& q3 W- A% k
- h" S- P. @- a3 `
/** SWDIO I/O pin: Set Output (used in SWD mode only).( t% h8 i6 I) U, {* R
\param bit Output value for the SWDIO DAP hardware I/O pin.
& I4 M* |0 z8 v- W1 Y*/
8 {6 u* _" ~5 [$ {* i__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
9 a1 M7 a$ b- h3 L  I  Q  SWDIO_TMS_OUT = bit;- t& U" i" F1 @: x3 t5 Z1 Z
}  Q* B9 z2 |0 `1 x# O
/ U7 I, C; S% p* U9 h
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).3 K5 B( q8 \: q2 m/ l. G  k; q
Configure the SWDIO DAP hardware I/O pin to output mode. This function is# l$ D0 n! @. M0 w8 I
called prior \ref PIN_SWDIO_OUT function calls.
' a& `2 p- s& r/ ~' u; V*/
& t0 B/ l4 C( \4 [4 P" J" q1 d$ j__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
' k, K5 L4 y! X' F3 Z  SWDIO_Output();3 k  T2 B" p: {2 c1 \) A: q% O
}
; ^3 b: Q! }& |, @  _5 v6 i' j8 b( C- p: j
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).4 u3 \3 h7 D% C5 r. V8 @; [/ B5 y
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
- r% ]0 c% n# f2 k( k! B- b! Ecalled prior \ref PIN_SWDIO_IN function calls.
1 T; T' E- `- g+ w' e( y*/
9 T. b  V$ i; ~6 p( D1 q__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {4 P) V8 P, ]0 J. `* v& o
  SWDIO_Input();+ B$ l* N9 w, Y' `1 I7 A1 y5 D- r% n% m
}
3 h, L& ]' ?: B3 @: |" u
( Y& V7 v& u3 j0 n! \楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的* C0 L! g% i5 F8 R6 M) M- e& F) L$ @
即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
# a. I: Y$ W2 z; v. R: C+ g6 t
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版