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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。
$ k3 K$ ]. I2 k7 B0 L
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50$ r+ u% b  F% Q) i6 {8 \
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
5 p/ P. x( _: ~2 i9 W
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。- Q9 F$ n5 Y' S% p5 j: y
  Y3 }+ _' \6 I+ L
软件复位是另外一种情况,需要向目标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
8 L  R" {* _" _& Z* Y可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

& {) c* {; B; h3 `& R6 R3 L1 ], BnRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
' |! ~$ _& r% k  E" ^: p$ F2 t' R你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。  y0 w5 S0 p9 H( B  R* ]6 n
9 f8 t* H: y$ A0 x
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 * C( W' j9 V1 s' U6 ]9 d: J. N- L, U$ o
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。. r- m; o0 V) y3 Q% h
1 L3 F; o' X1 X6 g: t
  ?) s( a& }! Q4 L# \5 h$ c( J
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?8 q% T% ?( k  G; M( j  m
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
- J) `7 ?* n0 ?6 @# ]
起点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系统,轮询执行
7 z* ~/ L. ~4 w) f, q7 I/**' U+ W% ^4 m4 l! q
  ******************************************************************************
" x, X# k! }' x+ g# j  * @file    usb_endp.c
7 Z$ `: o8 s1 W9 K  * @author  MCD Application Team
4 y+ B- ~/ ?! U* f* i0 d; g1 s2 R8 B  * @version V4.1.0
5 _0 a& F* r8 ^" ]$ C" {  * @date    26-May-2017
7 S) n0 {1 a' Z' d: p  * @brief   Endpoint routines% t6 i3 e( q; d8 s% W
  ******************************************************************************
% k( o" Z1 ^8 Q# n" L2 m  * @attention
/ H3 _' s2 z: M! K# s  *  H: l% Z  q) Z$ _. x3 Y6 i$ }
  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
" Y2 `+ {1 o% {  *: j9 v2 Q4 P- E% a
  * Redistribution and use in source and binary forms, with or without modification,
* _* ^( D, d, f9 q7 j9 o, I; c  * are permitted provided that the following conditions are met:
+ l! e2 M  B# z" u- M1 Q2 ^# N2 U  *   1. Redistributions of source code must retain the above copyright notice,
6 B( _4 g' G4 c( s  *      this list of conditions and the following disclaimer.
: V) N, y* ?0 H  *   2. Redistributions in binary form must reproduce the above copyright notice,# r+ @3 R( {" a& Z6 R0 ~
  *      this list of conditions and the following disclaimer in the documentation, r* c- o( Q7 h  r4 j
  *      and/or other materials provided with the distribution.: ~! f4 A/ [: N' Z0 V4 b" [7 ~) M; C
  *   3. Neither the name of STMicroelectronics nor the names of its contributors7 q. c# G7 i' p  B' J
  *      may be used to endorse or promote products derived from this software- R, M* u) n& a$ B4 H' e
  *      without specific prior written permission.
+ }; B8 D8 y/ v8 T; f8 \8 H  *
5 I; L# G4 n1 F  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
: H2 H- X/ h- j/ ]4 c6 s# x  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE9 ?: v1 v6 j$ q8 e& I3 d# J
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE; Q# G' w8 e( U. h9 |8 b- v+ [
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
) r3 T# E$ G4 @- J. A' L  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1 r0 y! B0 Q! S* I. a0 [- T& m5 V2 z$ b  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR# Q$ C- t% q" p3 n3 Z' N6 Z
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
" e; G4 w- w" p7 `  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
( ]) v4 ?9 U; W! `% L- U  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9 N7 ~" o/ X7 N' e' q  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 ~  [0 W' d9 w% q  _/ C( a( C  *  C: t, H* P) S* Z1 ~8 |: ]* _
  ******************************************************************************. y- z9 R" q8 ]! q3 r
  */
7 m3 c8 O( A9 t6 S! x5 @, D/ a
" c9 j$ w, S% R' ^4 }/ A$ B" h' N' J0 O0 @8 j& u; c- A
/* Includes ------------------------------------------------------------------*/
: x( B) ]3 v1 U3 |; h7 @#include "hw_config.h"
; ?; m! U% k7 g; ^+ R& b0 o#include "usb_lib.h"( q6 ]. d$ h0 q  X
#include "usb_istr.h"
- @5 D$ J$ c4 e! L- l3 f#include "stepper.h") k1 Z1 D/ }% U! @" W8 Z
#include "string.h"8 x5 y+ a8 [9 j) D0 N

% e. c5 L* J2 j/ E. t  h#include "DAP_config.h"
- s. ~* H, e; c2 M, |#include "DAP.h"" G% F2 P5 p9 M: Q# x

6 v( Z! T8 C6 E1 z) l5 D# e$ ]! A0 [% T  D0 o0 x2 x% K
/* Private typedef -----------------------------------------------------------*/
  c; V5 \( z1 d% ?$ T( P/* Private define ------------------------------------------------------------*/
* |2 G% c/ ?: |2 ]% a- ]* D2 J/* Private macro -------------------------------------------------------------*/) o& f: y/ Q" j0 `6 w  f: `* i- Q
/* Private variables ---------------------------------------------------------*/
5 I# L( c; o) _! D- ~static volatile uint16_t USB_RequestIndexI;     // Request  Index In
  y. O8 U4 }2 P" C7 h4 e4 }( astatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out3 x. a, F$ n$ ], }1 K
static volatile uint16_t USB_RequestCountI;     // Request  Count In
* X  L; S0 O* q; t! q$ zstatic volatile uint16_t USB_RequestCountO;     // Request  Count Out+ V7 |0 S8 u* p  I  g% O
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
& p% p# v* A7 I& h" T8 ~6 Q, @2 y* S5 m, W9 i) g$ j1 |$ f
static volatile uint16_t USB_ResponseIndexI;    // Response Index In+ c1 w. ?8 j* j" x- e
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out1 f3 `" ?: j; F2 ~9 n
static volatile uint16_t USB_ResponseCountI;    // Response Count In
, L8 h, T! |( W) S7 astatic volatile uint16_t USB_ResponseCountO;    // Response Count Out2 n# ?* O* u/ [
static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag# v7 _% s( w; j+ {, O  N, b. b1 a0 o
static volatile uint32_t USB_EventFlags;/ ~7 l& C8 ~$ o: |7 q! N0 t' B

1 {. A' O/ _5 E, m, c6 L2 F) lstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
# r. G( G, e3 e' ~static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer) _1 v) l2 O; r1 O! }% B
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
/ c- X$ v5 g; @; i) H- @- P$ o& _# b+ l9 ?
/* Private function prototypes -----------------------------------------------*/1 E- x# Y! k0 p# j% n! }
/* Private functions ---------------------------------------------------------*/0 w% v' l- X4 p. `
/*******************************************************************************4 A1 G6 j9 ?! q0 s' ~4 O' F
* Function Name  : EP1_OUT_Callback.
$ R2 h0 z: w, S2 X" i* Description    : EP1 OUT Callback Routine.( I9 {9 P  p5 ?
* Input          : None.
3 ^. s/ j9 t" ]  i9 V# I# _; F* Output         : None.
# M: X. E9 ^0 q' d* Return         : None.9 V* `" R/ x% g7 M: }( p
*******************************************************************************/+ S4 P* q! R: y0 [
void EP1_OUT_Callback(void)
% @$ D$ c) m9 D; O9 s{- ]+ o1 e( t9 g+ {; S! y
        uint16_t n;, r5 I; J) X) p0 b  J3 `4 Z0 k

- W6 g  R" F! c8 G        n = GetEPRxCount(ENDP1);
3 J, W* e- h) {4 k& X+ H        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);* m, @% C: k0 q. V& S
        if(n !=0){
2 u2 Y- B3 ^- Q1 x                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
+ B7 I3 x3 c) J* C5 _% t                        DAP_TransferAbort = 1U;9 n  A6 c2 x# _2 I9 W
                } else {
  G/ q6 o6 i+ C5 z/ Y                        USB_RequestIndexI++;
4 {0 Z4 r5 }  g0 d      if (USB_RequestIndexI == DAP_PACKET_COUNT) {6 V# t3 f- b& O$ [1 g
                                USB_RequestIndexI = 0U;" ], I6 n2 r) b& Z2 C
      }8 K6 l6 s4 |5 x% S# i6 j* r3 D
      USB_RequestCountI++;- U/ [: e2 A- |6 _" {; e
        USB_EventFlags = 0x01;
' T5 g' f# _4 ^; B" s    }
  B; ]; X1 \0 |4 ?* S. C- d; Z        }        4 j1 r4 F: Q5 G8 r# @8 w. A
        // Start reception of next request packet8 X, Y8 Z0 z) c2 U2 R( K0 U7 ^
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
1 O) D% @0 p6 {1 Q4 x4 w8 h5 K                SetEPRxStatus(ENDP1, EP_RX_VALID);/ X& U' f/ G# t
        } else {
" z) T8 I+ |* u7 G# X6 j                USB_RequestIdle = 1U;$ q' U6 ^) A- ?) Z
        }                        ' D% _8 n5 t; K/ A4 f+ D" O' f
}
# P' A7 a( s, ^9 ~8 e- A% R1 c+ F  D* C' L& |( [/ U- o5 t
/*******************************************************************************( L8 c: g0 `4 {' f- E
* Function Name  : EP2_OUT_Callback.
5 n' l1 g2 a. H- F- h- ~  |* Description    : EP2 OUT Callback Routine.9 [- w7 n( f2 h2 T! s# Q
* Input          : None.
( U* }" X2 e( ], j* Output         : None.2 b$ m0 W, X' ^$ o, I; [4 e3 [6 ^0 Q/ j
* Return         : None.! H0 P; n6 c% \
*******************************************************************************/, J$ K+ t; n% ?6 u1 e  M1 f
static volatile uint32_t TX_n;
) J' T2 ?, H  A# g! H- g+ Pstatic uint8_t *pbuf;. ^  E0 Z$ ?- ~( x
void EP2_IN_Callback(void)
/ V  D+ w" {. W  {+ K{
  g* `) e: Z. E3 v        uint32_t a;) u2 z, t* A% B2 y2 A  b& Q4 D
        if(TX_n>0){
2 _2 J0 q. G3 Z! S& `                pbuf+=64;
/ b3 v! P1 |" ]0 W                if(TX_n>64){
# s/ x$ G% a4 |                        a=64;2 a" v' a2 g" \+ d% O! U
                        TX_n-=64;
8 \3 e. Q, }* B( K8 O9 {1 y                        , q, h( r2 w- v; S3 D- P9 i
                }else{' a( _# l$ R5 m6 c/ _
                        a=TX_n;6 X# v# ?& b0 t0 n0 T" M) N: Y
                        TX_n=0;
0 D* q9 O4 w9 e& b) d( q: j0 e4 [: M8 W                }
3 D3 g7 q* d9 t8 O0 a7 ?6 w0 F               
4 v( n) J# V  {        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);5 ]$ w$ t: L4 q# J& e3 F% x. H) H+ ~3 T
        SetEPTxCount(ENDP2,a);) s6 Z6 `- {( X+ i- V
               
) K: H$ e' L, b' V" Y        SetEPTxValid(ENDP2);4 x/ q2 K/ |9 l
        }else{& H! E& z, W0 @; r$ w/ q9 S
                #if (SWO_STREAM != 0)
' z. N: G& j5 C% n$ y                SWO_TransferComplete();
0 O" z. P; C0 J& {1 g# ]3 x                #endif
" B+ V9 R* w$ f: }# u3 R        }
+ N. N/ K7 l3 `. F. s4 @" M}
! g6 D/ U9 P) x% b, E
6 q3 H; V# I# D9 }+ D, d" h/*******************************************************************************
$ i& g% B0 |0 C6 @* Function Name  : EP1_IN_Callback.0 K; K5 e, f! }( l5 V* N6 |( J& e
* Description    : EP1 IN Callback Routine.9 m' V. ~; ~. m; P
* Input          : None.0 B4 K% P& w' i! {/ \
* Output         : None.1 P3 ]/ `& T5 p8 \1 ?$ O) {$ I/ ~
* Return         : None.
' v/ Y' c2 d' _*******************************************************************************/1 y, D: ?8 z# n" A! ~
void EP1_IN_Callback(void)3 |/ i- ?9 w4 r/ p+ g  c5 O' @
{% m' c3 N7 }) o: b* h
    if (USB_ResponseCountI != USB_ResponseCountO) {
. t* Q1 ^  e9 n! ]/ E) {      // Load data from response buffer to be sent back2 h* V/ w  V5 d/ L  U: y3 t; z. M
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);. `9 u$ L8 o# u1 A* \6 c% k) `
                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
% T3 K+ `7 G0 A5 c( q) l                        SetEPTxValid(ENDP1);                        
% P4 h# v- Y- R' u9 N) d( {9 T      USB_ResponseIndexO++;4 q  s7 C: V" |# y4 {. o# S
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {7 j! s9 V0 ]0 Y6 S# C6 {
        USB_ResponseIndexO = 0U;
2 W0 m* ~$ w, E9 @3 U- _* E8 L      }
5 A" X) y8 n" }! |7 w  e      USB_ResponseCountO++;: G5 @/ h( v# U  f( K* Z
    } else {* C3 J+ U9 q5 I# X0 Y6 c$ r4 V% p
      USB_ResponseIdle = 1U;; s1 w; f# L+ ^+ Q- o1 @
    }  
1 F5 J5 o6 w0 x5 W+ \" h}
9 I( z+ A0 k: b, a( b; m- x
5 j: n' n: m! }& a2 W& r2 T// Called during USBD_Initialize to initialize the USB HID class instance.$ t7 ^+ M" A% P8 a
void DAP_FIFO_Init(void)
. a3 e: w- H: }6 c; i6 i. x4 a* @) W{1 R; e% Y. ^1 J  _
    // Initialize variables
3 W# q$ [$ d' Z    USB_RequestIndexI  = 0U;" |1 J% U+ U4 r' i! W0 O  _
    USB_RequestIndexO  = 0U;
" C1 V1 d& F' B3 i6 I' ]( L+ m8 I$ B. `    USB_RequestCountI  = 0U;9 d. Z) v7 Q! a4 e3 R
    USB_RequestCountO  = 0U;
( i9 ]( m6 k; L1 m+ ?9 k    USB_ResponseIndexI = 0U;
: @# D! I) I6 x) X6 y) I) c    USB_ResponseIndexO = 0U;' O4 m5 i8 B/ s1 T, P) `
    USB_ResponseCountI = 0U;8 e7 ]2 \" M9 V' _  }
    USB_ResponseCountO = 0U;
8 @5 q& F; f: T9 ^( x    USB_ResponseIdle   = 1U;
) k, H0 y1 [* y/ f  S3 F    USB_EventFlags     = 0U;" A! k$ o+ f3 v
}
: [# `+ b' B/ c8 W2 T& }$ x- h6 ?) l8 {1 p, U3 r
uint8_t DAP_Thread (void) {
* X0 n( g7 X  M. v2 V. E  uint32_t flags;* Z. _) g( Z1 ~* N6 h% k" V
  uint32_t n;
$ I; o2 |  z) _" L
4 l! d  b# U' _( B  J  //for (;;) {
( I. @0 W5 ?' T  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
+ J% W' [# ]2 u0 f4 k6 l                if((USB_EventFlags & 0x81) == 0)
! ~, J6 @3 q# ], A# s& z) C/ U                {
$ T! ?6 m1 U$ \                        return 0;
. X1 n% \( ]3 V, f; D& H  v                }) u8 T9 q/ [  j0 c. r% F
                USB_EventFlags &= (~0X81);9 m! g- l: q7 [& W
                / X' h% F/ k0 ]# j: a+ H
                                        6 A1 L$ t+ F! w( g& X1 W
    // Process pending requests
& M; o7 k5 u) g+ z' r    while (USB_RequestCountI != USB_RequestCountO) {1 E$ O" Z( b: V5 `% X
                //if (USB_RequestCountI != USB_RequestCountO) {
$ I* H; W1 H! t/ r6 l      // Handle Queue Commands
% O$ ?. V8 k! {2 c- [8 s3 B; e      n = USB_RequestIndexO;. g4 }4 e  T: T, R$ |4 _
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {7 u6 Y# M0 ^8 g4 n- U  Y' K: t1 {3 T
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
% \0 {" `$ S- @7 t/ _. `! C        USB_Request[n][0] = ID_DAP_ExecuteCommands;' K  v- n4 J  k9 u" C
        n++;
0 c) A4 h! f$ p% Y4 |9 b# t# t        if (n == DAP_PACKET_COUNT) {8 b: q% U8 s, |2 P' @+ {& c
          n = 0U;
' y) t5 I7 S4 K: Y  H9 E        }
6 k. E# `5 u) O& L0 s, `        if (n == USB_RequestIndexI) {2 X/ y8 h" @. A
          flags = USB_EventFlags;3 l& [: q( R; {! g/ A9 i  ]6 x" ?
          if (flags & 0x80U) {
" C+ p+ y$ O4 y- d/ R            break;* u0 b+ m' `1 |
          }
* ~. W! b: v; \        }( w  h# D% E- s  X: z* q
      }5 A  C; r: F  U! h
  @4 G) m, p' b& ?3 {2 ~7 U
      // Execute DAP Command (process request and prepare response)9 P  s2 q* x- C5 A
      USB_RespSize[USB_ResponseIndexI] =. g8 t9 x! ?$ M
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);8 a& _4 E. w% _$ w2 k2 @
: ^* X$ O6 ~* M0 Y9 `% L
      // Update Request Index and Count
, `5 K. w8 w- b: r3 ^      USB_RequestIndexO++;- H( ?8 ]. c. E8 J5 F& ~2 x
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
. F/ y1 h0 w' Y. ^2 K4 D        USB_RequestIndexO = 0U;
+ ]2 U7 d+ N, u& b! ^% o- q* g  l      }
% _9 Q+ ~" ^6 ]      USB_RequestCountO++;
, ^1 c: s, O, p
4 l# E& z, o  X7 |% G) F5 l      if (USB_RequestIdle) {
2 J5 t. X* O/ H/ |6 H  Z3 D        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
7 {* a* _+ v: S  h$ Z8 [          USB_RequestIdle = 0U;
; K# `. V, s" }" O7 m8 l! D          SetEPRxStatus(ENDP1, EP_RX_VALID);
; m* F) P/ ?5 U$ @  L% J        }( p, r* c+ z2 u8 Q% b; z- }- `/ g
      }
/ K- [  Y4 `9 C/ W8 I7 k* K+ l7 j
4 L, U! p& E; v; }      // Update Response Index and Count
; X% B+ j6 D5 g" e      USB_ResponseIndexI++;
% p- `4 N) g! m& S      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
( U/ b+ d1 L" [$ ~& [7 Z2 N        USB_ResponseIndexI = 0U;
9 v$ q0 `- T  R' h      }% ^7 W; n) M6 i0 ?1 x' Z3 [/ z
      USB_ResponseCountI++;$ _8 v3 B5 ~4 G# U  [

7 j1 x. L1 `: x. I/ {      if (USB_ResponseIdle) {7 T0 ]+ r5 g  {! R3 p1 o& |5 ?
        if (USB_ResponseCountI != USB_ResponseCountO) {
: r+ ^5 a  i, J' @# B8 O: [( V          // Load data from response buffer to be sent back9 K1 Z5 I' @' i/ \( l7 k& ~6 O
          n = USB_ResponseIndexO++;
: I" u- V& C) O( G3 g7 O7 v; g9 o# \          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {  m$ ]* N+ F" G: s& y9 {. U
            USB_ResponseIndexO = 0U;% R1 i) |2 e: k+ w/ v
          }' z0 I2 F6 f- u4 `1 C
          USB_ResponseCountO++;
+ M4 y# U5 P/ V8 B: d3 M9 `          USB_ResponseIdle = 0U;: L) c$ @5 J4 \0 I4 Y4 p4 |
          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
. F: T+ e3 X, ^& H) H                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
. k- f1 N; S$ J# b                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
; ?  X4 u/ u6 Q! L8 K5 _                                        SetEPTxValid(ENDP1);
# |  s5 R' p. y: [0 b3 A( F; ^& [        }
: d1 z4 o- j+ Y4 E0 i9 a      }
1 m% G& y; R3 [    }1 T. t, M7 J: {6 w9 @' I
        return 0;! G5 G9 U- o5 v% I6 l6 H5 L
}! {3 V, `# |7 w5 u3 |

* l( m; p9 `/ R/ c: l. ~  W// SWO Data Queue Transfer
0 k) X2 g( ?* `6 ~//   buf:    pointer to buffer with data* |9 H) l" ~/ Y
//   num:    number of bytes to transfer
2 S( f6 d' f6 @4 Dvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {" z, N& U6 r% z% x/ w( Z; @1 W
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);! g# Q! D' }' K" j9 [* q# D% J3 T
        uint32_t a;% p4 s/ a. C+ i. s! _, X
        
- @7 u4 j1 q' Z5 t- o        if(num>64)" ~. \  y1 |+ v, e
        {
+ B1 V+ }, D; Y! F; ]) }                a=64;: b/ n9 i1 n1 l2 a. q9 `
                TX_n=num-64;
0 ]% G/ F+ j+ V7 D( n                pbuf=buf;
# ~: W. q; M/ z  d  u( z5 |: V0 _! j( [$ f
        }else {
3 c; j3 x4 [3 C% U                a=num;
' J1 c7 Z; g1 J" F2 [                TX_n=0;: D6 e5 B5 K- A8 e- L
        }
2 V5 K1 `9 G* s6 i        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
) U' |$ ]5 C) J* j+ }+ `9 A; [        SetEPTxCount(ENDP2,a);
+ s; }, M" S. y( \! N, X; O        SetEPTxValid(ENDP2);0 @7 o* B, g2 v/ j4 I6 u+ P' h
}4 M2 ^  {! ~4 }& b4 ~1 d; b7 q

$ {+ A& x$ ]" `3 g5 Z, d1 h9 c6 `// SWO Data Abort Transfer8 F7 r* G" D  V4 o' s9 D& \( c$ V
void SWO_AbortTransfer (void) {) q  N9 ]+ x4 o8 A" P  W' i. U
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
8 d( q- B0 y7 m7 k$ l" D5 o        //SetEPTxStatus(ENDP2, EP_TX_NAK);
' @3 U# t" ?9 Y/ x6 g- u& r, h        SetEPTxStatus(ENDP2, EP_TX_DIS);
) s& e  N9 s3 l9 Q2 ]        SetEPTxCount(ENDP2,0);. U- p! p4 I& t- l" j, L. V
        //TX_n=0;
- ]0 ]; t; z: R- n9 Q) Q& T0 a}% o$ p9 M* i( c# ^: v) |
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/9 B* j/ o8 O, |& I
) z/ r+ J" s! G* {9 S
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
/ |' B0 _3 l7 TDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了& d( e- @- ]; F) n6 ?
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {. |2 U% G, w4 ~" s( c0 Z: c" `
  return (DWT->CYCCNT);# G  y* v9 v. Q7 n
}
4 A( `" q; L9 C" x% |
/ ~. [6 }4 I. c( F* @) T9 [void DWT_Init(void)
8 I: s5 q, ^0 a+ U- z8 W+ k{: _4 i. [3 j$ J) @  L' g$ l
    /* 使能DWT外设 */
1 c! m" `/ J# k* k    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
3 d2 D# A  C" {$ d: I0 m
6 M% d* N9 O3 L: z% s    /* DWT CYCCNT寄存器计数清0 */
) _0 b: W3 \1 F. B. i    DWT->CYCCNT = (uint32_t)0u;2 X! E2 `  o5 U" Z/ F
0 P7 ]$ ^% L6 t; |; \
    /* 使能Cortex-M DWT CYCCNT寄存器 */+ q8 Y4 _1 ]/ b; Z% W5 `) K
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;0 i1 f' x4 a4 }9 N* l, P* r
}
4 N; w6 B4 E# p! D7 B2 l        4 b6 x/ _! ?: N4 r: W7 [

; V/ Y! i2 @, t$ |- ^3 r然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率( w4 ]( @5 `4 K8 p

3 p, D3 K5 l- C* R! G/ p3 _* W然后改为使用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不香么?
: |, u5 k2 W" Z' {* f声明这个变量static volatile uint32_t SWO_EventFlags=0;
& q8 _& S: ~2 O  v$ m在SWO里每一处调用osThreadFlagsSet的地方都改为如:
: M7 p0 h+ `+ L/ u$ k//osThreadFlagsSet(SWO_ThreadId, 1U);! L! k  |3 U2 T# b* p
SWO_EventFlags = 1U;( i% g) ?. I4 t$ T# g; [$ [
8 X/ Y3 R" s. `' i9 G& K7 V( ^
! p" z1 n1 k) V+ E
// SWO Thread
4 T1 V3 y  ^8 G1 ?4 V3 w/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
% P1 m$ W2 C; H. B! y0 r% d  //uint32_t timeout;
8 ?, m+ F. b, T  J5 k/ N  uint32_t flags;3 o) Q" n% Q6 J/ n' _
  uint32_t count;
' Q% i; u0 c1 G, J+ V  uint32_t index;. I% q5 i3 p9 E
  uint32_t i, n;
8 g6 l; M0 V0 n  //(void)   argument;
& T" Y1 w: z' |1 Z: s- \# t' z( S1 O; k9 ?& s, d; |
  //timeout = osWaitForever;
: \( E% n" S( g) {0 ^  G5 t$ X2 ]9 Z
  //for (;;) {
' W  g5 Z1 c+ E% P) q6 x. g1 \    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);1 }8 r, R# V& E: x# V" f3 x5 \
                if((SWO_EventFlags & 0x01)==0)return 0;
7 D2 V! v! Z( @2 L         
: u& d1 T/ I# ?4 _( j5 S5 h                flags = SWO_EventFlags;) @7 e- C+ ^4 f
                SWO_EventFlags = 0U;
* H& L  h4 b2 V0 p/ E5 B, v    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {( [0 o% @7 {" Z* C0 D% Z5 N
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
) E" W( |1 F5 T+ u                        ;
; y9 ^; I" w, o    } else {
/ |4 B6 l6 p. ~4 }      //timeout = osWaitForever;
1 \) S0 ~& Z0 A8 o* t2 @      flags   = osFlagsErrorTimeout;
# a- }" G6 C5 n0 |    }
- ^- }3 N9 k5 G2 S! m    if (TransferBusy == 0U) {6 [# f% B, |8 S9 W, W
      count = GetTraceCount();3 M9 x$ J0 |9 S; ^7 u+ [% D7 |
      if (count != 0U) {$ B* ~- o! F; i
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);& D4 T( Q& _3 q' u! g1 @* m" H; C
        n = SWO_BUFFER_SIZE - index;
1 i/ V! }1 h7 Z/ m0 j# H' @" j        if (count > n) {
  H' G# C, S) u( K          count = n;  p- ?! V1 L1 Q6 t
                                       
  o% E  G8 u* K6 h        }
' i* t4 m4 Q  s/ K7 [! ?                                if(count>USB_BLOCK_SIZE)
# I7 J5 |' z/ f" f( C                                        count=USB_BLOCK_SIZE;( ]" U+ [1 T  h% J+ n$ b8 s
        if (flags != osFlagsErrorTimeout) {
8 F4 V* X9 o: ~/ A          i = index & (USB_BLOCK_SIZE - 1U);+ B/ |. M3 L/ j+ F1 b5 Q
          if (i == 0U) {
: ~. e8 Z7 Y, U            count &= ~(USB_BLOCK_SIZE - 1U);+ ]; H, k) }  g' M
          } else {4 E8 R# R+ j( ^6 }1 J6 Y
            n = USB_BLOCK_SIZE - i;) d; e- C$ l. X5 C& U! F) N& I, h, K
            if (count >= n) {
" t' V' ?" U3 H! z. I              count = n;
. E  H( n; t" D            } else {
6 ^% ]+ F; J, J; m  A              count = 0U;  R6 }0 \/ i1 |6 E' k
            }) T; _/ [0 L% M' ^
          }
: {1 ~# m; r# m# J        }
& y3 t% c+ N6 D9 T: N! c        if (count != 0U) {# N4 \1 A# f+ {+ d" y, B) p
          TransferSize = count;
4 h1 {/ p. D, H' ?$ r          TransferBusy = 1U;* v, e  e0 z% a3 Z0 v
          SWO_QueueTransfer(&TraceBuf[index], count);1 H* ^$ z& A1 W7 G! I& T
        }$ _' C8 F" u! H9 m9 \
      }
: ]$ D1 M$ W) p2 `7 \    }8 A4 ], p$ g' e2 O. u
  //}1 \8 o! Q- i$ E& G! |3 L: n/ @! g: J- y
                return 0;
/ c' z' r& w, X, [/ f}/ c' W% }1 x/ Z+ B- H# Z' J
利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
! A% q, y8 U' c7 Z#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
; ?# Q3 j3 T$ A+ P: zstatic volatile uint32_t SWO_EventFlags=0;
0 l) \* Y$ F9 a' X9 \$ Cstatic volatile uint32_t timeout=osWaitForever;
( |; d' d- V# B: e$ e6 C! nstatic volatile uint32_t timeWait;! D0 s( v  p8 b( W% G! i
函数改为这样
- t) z2 f# @' U" s/ |% J/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {$ A: H% `$ {* i3 F: c
  //uint32_t timeout;
7 o9 q7 F: w2 M! C# r$ U, S  uint32_t flags;
2 J2 R) B2 h9 [- O0 A) S# G) ]7 s  uint32_t count;2 L3 w/ ^4 V; D/ L' n0 N7 h
  uint32_t index;
2 b2 e3 P* ]1 @  uint32_t i, n;# F+ i* ^7 D8 W9 k$ q+ `: K2 p. B0 w
  //(void)   argument;
9 V# @1 U' J$ {/ f- u3 z6 Z
# F# Y' T" g9 b7 ~! C2 N1 l! F  //timeout = osWaitForever;
5 d+ x  h  L" W0 J! G, o' j( Q
  Y! s0 v8 o! K; ^- f# R  e  //for (;;) {
  ^: U- A) R( {) B    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
% v; S; g; j, K; O0 M. G                if((SWO_EventFlags & 0x01)==0)4 G- J# f* \3 w3 z1 V5 h" R
                {
2 H+ f: v8 M9 j% N0 p$ @* m5 I                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
, K3 |, z. {' X! C% Z- {/ z                        return 0;
: t$ c& @+ \5 z8 B9 u9 Z5 [                        3 m0 B( y0 r" e$ |+ ~  f
                }
2 {0 }( q  P* C1 n# E: p         9 @- M5 B: u" g' Y& r6 k1 q  S
                flags = SWO_EventFlags;
$ P- W/ P& G3 L                SWO_EventFlags = 0U;
+ o% L( [. L7 `" s    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
6 t; a0 j# ], P      timeout = SWO_STREAM_TIMEOUT;0 L7 Z' o$ C1 v6 w2 M, ^4 @! O
      timeWait=DWT->CYCCNT;
; [" L$ `  P( T" `3 A    } else {
; J* S/ Y, ?9 u' K4 ]3 K& _      timeout = osWaitForever;
/ I; o) Q! c3 C/ [" u      flags   = osFlagsErrorTimeout;
8 {7 j5 h' B/ ^- H4 R) `    }
( J) W$ B: j# Y; ?7 F9 @( P    if (TransferBusy == 0U) {
8 b& |! O/ n0 I  E$ g2 O      count = GetTraceCount();/ |" C) b( ]2 c4 \" o
      if (count != 0U) {
; Z) O, `1 y: t5 s        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);  n& z7 E- Z) D% W
        n = SWO_BUFFER_SIZE - index;
# |+ k& C) J! c% ]7 M        if (count > n) {
( U% U& A; |& i$ X7 b+ c          count = n;
$ |6 t) }7 r; M. o1 u, M/ @: v                                       
$ O' ^1 _, ]& a: b3 S( }3 l; _        }/ _- ~2 T/ `( Z
                                if(count>USB_BLOCK_SIZE)
+ h5 ]6 l1 J" d' m" e- ?                                        count=USB_BLOCK_SIZE;4 B8 [8 [7 Y3 ?8 w: X
        if (flags != osFlagsErrorTimeout) {. u/ K5 n1 l6 A% O9 j  Y
          i = index & (USB_BLOCK_SIZE - 1U);# f6 I* D1 G; p# |
          if (i == 0U) {
. ~! W% m; W! P( i* }; @1 k2 x6 t            count &= ~(USB_BLOCK_SIZE - 1U);" r/ A8 R0 F4 u! h3 ?7 p; g
          } else {2 k+ s, S, {0 m2 V3 l
            n = USB_BLOCK_SIZE - i;9 Y  w; |. x) f' o6 c1 R! q
            if (count >= n) {
3 P  u3 L9 E* ?) ]              count = n;( G( _2 V: @1 [  B
            } else {/ ]. m9 r. o/ ^7 c$ V% G: m
              count = 0U;
1 p; C/ s, ~" O            }5 r0 Z! p  x$ o5 @6 ~0 L8 }
          }9 W7 G5 _4 A# N$ C+ A
        }( c# @" w( d: \
        if (count != 0U) {
) m# m$ L. J! l8 {7 l% ]- j          TransferSize = count;& w' g+ r9 E  D# }2 w1 w
          TransferBusy = 1U;& I$ r, M5 k- C- ?6 x# ]% K% W
          SWO_QueueTransfer(&TraceBuf[index], count);7 S& p- }$ @0 u5 Z# k! v5 H/ d
        }
4 V1 {) \$ L6 z. ^! ?: i      }
% u5 P* Q$ V/ C. ~2 R5 Z* p    }0 ?8 V, R4 {! j" R/ C0 C
  //}
9 B& _" O7 f- }9 J                return 0;; B8 L. H) F6 T4 b: B" J, P3 `
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了/ E$ L3 ]2 y+ N# S

4 O9 S" M7 v/ z. y* j: }" ZCDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率1 ?, W6 S- g) ^

' b. e) c) Q- b6 u) d+ V: O, C0 T3 R6 e" ?2 p
int main(void)
4 h0 ?- p; L8 @0 Z" Y4 V{
. H+ P& G+ t+ B6 ^2 X  DWT_Init();
( @2 t2 @; `/ ]" ]        DAP_Setup();
3 q: q: F# t) N, X  USB_Interrupts_Config();, Y$ U1 o6 n# ]6 G" J5 B. q
  Set_USBClock();
+ P9 c# q0 n  I4 o0 \3 G  O& Q* z  USB_Init();
, a6 M0 F, q6 b        //TIM3_Init(35999,0);
' O% _: b( O. d# [        //TIM_Cmd(TIM3,ENABLE);
" M3 X: L2 m% P        
( D. u% I  @2 {4 T/ a0 o$ L$ }          Y9 b. v, [0 d" q- J
  while (1)
! r5 U2 X4 s! t$ u# m  {( j8 S% b) y4 D- d; g' i
                DAP_Thread();
& x0 R% X! j; J/ K. q& I# M; m                #if (SWO_STREAM != 0)% y" `. R3 h/ j% [  y( Y; R
                SWO_Thread();
' l: j  a6 h2 F( n                #endif% Q2 h( G1 _8 h( p6 x. j# l: g
  }
- I0 C' G+ S1 N+ Y6 \2 r}3 K* p$ Q3 U* g- M( o3 X# E

6 G9 [! L( k$ A% {4 b2 [+ P# X' ]0 c对于DAP_config.h的IO配置我是这样弄的" }, G& O: Z5 U" x% N
///@}2 T8 k! ?( H9 }
// Debug Port I/O Pins
7 G1 w* K1 q: U* ?6 J% `* `
* h- R" l  }' P+ R6 E9 `// SWCLK/TCK Pin                GPIOA[6]
0 p( k7 p* B4 C0 W/ I! S$ v#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
) m- V3 ]+ X: k" n  M) o0 \+ F#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118: h* B+ }- _' m+ N

, ^+ m3 U3 ?# U; R1 |0 g// SWDIO/TMS Pin                GPIOA[7]
; Q- Y2 D* I5 o, ]#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C  j; S# [% \1 ~) w% y. r( \( `8 a
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C
! T' n% Z5 {; W6 C4 n7 Z* H4 o  m  `3 a( O) ?9 K' ?
// SWDIO Output Enable Pin      GPIOA[7]- D% [7 t. ~- o# v0 s
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \1 D4 h  h# W; O9 y4 h
                                                                                                                                *(uint32_t*)0x42210070 = 1; \$ N  J# U) ]- z: k8 U
                                                                                                                                *(uint32_t*)0x42210074 = 1; \( ]3 l- |5 U! \/ @" U/ y
                                                                                                                                *(uint32_t*)0x42210078 = 0; \
+ J( }6 e( c8 H' o( U. J- H) E# j                                                                                                                                *(uint32_t*)0x4221007C = 0;}
  d0 d. |# C3 W, G, G" }7 k) ~* r) m" j  Q) a6 q3 y
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \% C3 o7 w7 V# @/ e4 d' b
                                                                                                                                *(uint32_t*)0x42210070 = 0; \
8 b# q" t+ b/ n! G# @                                                                                                                                *(uint32_t*)0x42210074 = 0; \
9 i! E$ g" J6 [$ z$ ^                                                                                                                                *(uint32_t*)0x42210078 = 0; \9 x% R9 s: F9 {
                                                                                                                                *(uint32_t*)0x4221007C = 1; }' S$ G2 ^9 H9 J& w3 H
6 b3 X! r1 _, D! O* T* |
// TDI Pin                      GPIOA[8]+ V2 z9 y9 N% g6 n1 z+ q* ]0 N5 \
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
" g, m, k4 |% R#define TDI_IN                                     *(volatile uint32_t*)0x42210120
5 V2 Q- Q* y, R9 c  N7 u" i- q$ j, {: H7 N1 Y
// TDO Pin                      GPIOA[10]  }( W. m6 E% d% n( U! E) `- v
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
% Z5 p0 G# Z% ^#define TDO_IN                                     *(volatile uint32_t*)0x42210128. y) U" ^# R" Y) \6 @; w9 L
- }- ^% E0 j9 [: m6 v
// nTRST Pin                    GPIOB[3]" i7 x7 _: c8 I3 X+ Y, \' `; F
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C8 d4 K5 ?5 E4 O0 K# G' ?
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C/ e/ F9 ^, }) U% B% `4 L
. B. h/ S9 \( @1 O# o; Z
// nRESET Pin                   GPIOB[4]
: @) }, s' H/ y; \2 G, B#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190( ^  d) \4 @* g1 P" g. o3 m
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
6 \, a3 W# U6 g" j" H; j# b4 z( X' h- f1 w" {
// nRESET Output Enable Pin     GPIOB[4]% g. w; B4 R$ Y( {4 t+ L
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \% G- W7 a5 }( s2 p3 B" r* t- j( |% q
                                                                                                                                *(uint32_t*)0x42218040 = 1; \1 d9 w4 r9 z) ]/ H5 r" I9 v
                                                                                                                                *(uint32_t*)0x42218044 = 1; \+ k4 O) F2 w: ]& i0 r( z
                                                                                                                                *(uint32_t*)0x42218048 = 0; \
+ ?, d+ c6 B* O/ m                                                                                                                                *(uint32_t*)0x4221804C = 0; } / g. f% B2 _. P9 W* o; S! V
6 y, e7 k% r, r0 K9 m3 C4 N# ~% t
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
- {6 H. D5 H6 G; P) D9 H3 N  Q                                                                                                                                *(uint32_t*)0x42218040 = 0; \" V1 }/ @) j( H5 }
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
* s6 A2 [( C2 W: d/ |                                                                                                                                *(uint32_t*)0x42218048 = 0;\
  A, {. e* X5 x9 f                                                                                                                                *(uint32_t*)0x4221804C = 1; }
; U3 Z6 T9 K) u4 N
7 _" ]# {2 N- F; c: b6 T4 f
5 x4 {6 X# g; k: T- I. E// Debug Unit LEDs* p" K1 v+ n( m1 M

" H7 R" n# }: m$ M+ T: Q' ?3 Z9 G// Connected LED                GPIOC[13]
) h# l& L8 a6 d8 A#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4/ q1 i; f$ ]( c0 l
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
8 y) I% a  Y( Z- M7 `2 l
- }) w: f% |  n8 m#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \/ R, A- L4 N3 l
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
1 ]9 u0 I" X' F: u                                                                                                                                *(uint32_t*)0x422200D4 = 0; \6 P. S# J8 a, E1 R. O, E4 X4 a
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
, a" w2 H3 [, T% _8 |$ s) \9 H& p                                                                                                                                *(uint32_t*)0x422200DC = 1; }1 \% w: Y, g# g6 K
// Target Running LED           Not available% ]& N$ r0 ^9 `4 Y6 N! e
4 y% }+ r. k" u) a9 s8 j0 Q
// SWCLK/TCK I/O pin -------------------------------------
2 {" E$ z/ v4 Z7 Q0 i0 L4 ~4 X3 U/ r* u- {3 ~& e8 V
/** SWCLK/TCK I/O pin: Get Input.
2 Q  T2 m" l$ P% a8 s* K6 a\return Current status of the SWCLK/TCK DAP hardware I/O pin.8 Q1 K1 o2 ^+ B3 C2 s: i
*/) Y/ @4 E& b- ], H0 r6 t9 Q
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
$ p6 V' X- |2 I  return (SWCLK_TCK_IN);
  A, K3 c( d% q) ?' S, [: f}' g! `/ ~* _0 V7 o, Y% x7 I' ^5 w

1 C* S- @$ M  H) v. g) Q) L/** SWCLK/TCK I/O pin: Set Output to High.
. V2 Q, U* A# t8 b4 qSet the SWCLK/TCK DAP hardware I/O pin to high level.
$ O, D9 Y2 R2 g  d; O* l' ~% b*/! Q5 v3 N1 \9 G, ^7 e
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {/ P6 M9 p5 `3 q$ K: Q# H
  SWCLK_TCK_OUT = 1;
* b8 R& B+ Y2 B- T$ O}7 o4 s8 n$ c/ i7 g
, Z* M0 ], v$ S, N* z0 `7 o- F! |
/** SWCLK/TCK I/O pin: Set Output to Low.
. d$ u7 i! ?8 {3 W1 i0 {  I6 Y+ j$ G! ^" ]Set the SWCLK/TCK DAP hardware I/O pin to low level.2 s( n5 B7 H6 M2 j
*/
. }/ r( \- L% K1 X7 J; ^: O__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
) p5 ~6 e3 t7 m- ]! K4 ^  SWCLK_TCK_OUT = 0;0 G% d/ M9 M& f4 C- c/ p( [. a& G2 b
}
2 W; L1 d2 F2 E5 y; A
2 v- w8 \  J. I8 K
$ w% b6 a+ q# i// SWDIO/TMS Pin I/O --------------------------------------
2 H* X3 S9 k# M5 o" E+ t4 w
, S6 M. ?8 P* `3 P/** SWDIO/TMS I/O pin: Get Input.
$ w# n; w  ~6 W* X$ H\return Current status of the SWDIO/TMS DAP hardware I/O pin.8 q/ i  U+ v; ~4 U$ d
*/
& Q5 q) @( E! |% ]; `__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
0 t" y8 V/ Y9 K& d" {  return (SWDIO_TMS_IN);( l2 x3 T$ Y; e- z3 r
}" f: m' L0 h7 m
* Q- Q5 v% R2 W+ L$ s
/** SWDIO/TMS I/O pin: Set Output to High.
9 C8 n# f7 O1 k* g# lSet the SWDIO/TMS DAP hardware I/O pin to high level.7 [8 E% ?& _1 C
*/$ s2 J: u' h% r* d/ @0 g* @. e& s
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {/ M- x+ B  L' V2 I  c) M" m; p8 t. K
  SWDIO_TMS_OUT = 1;
* x# P$ S5 W7 v1 q* [}
9 V+ H) x- A/ l7 d" ?
: M5 y- w  E% m/ H  `( ?( W/** SWDIO/TMS I/O pin: Set Output to Low.
8 \9 q+ I( d' D/ w* k3 h9 ESet the SWDIO/TMS DAP hardware I/O pin to low level., `# N; B( g# o; o4 X
*/
' u- d  {! _2 w2 ]2 X, z/ {5 e/ x__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {
7 e) q4 m  T( ]3 ~7 r  SWDIO_TMS_OUT = 0;
7 @7 e8 I2 t$ _# r* ~  _}
& a, d3 u% `) b: Q# U; i3 Z; \8 {; o( e' j- f1 N- c8 D
/** SWDIO I/O pin: Get Input (used in SWD mode only).
" o* m; J4 R9 ]; _% E\return Current status of the SWDIO DAP hardware I/O pin.5 i9 ^% `' }2 V8 S9 @- M
*/+ [" l7 u( f$ N3 R
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
" A4 h8 Y: q  u( ~  return (SWDIO_TMS_IN);
7 U, ]8 L. ^  Z}
4 p6 O+ g' {. [% u, Q/ N- r2 f# n
8 l2 l' T$ }0 K5 Z' n/** SWDIO I/O pin: Set Output (used in SWD mode only).
1 O# F3 ~; L2 c7 ^7 h\param bit Output value for the SWDIO DAP hardware I/O pin., l) A8 f( g* j" C
*/- P, n" v! S/ D8 e$ e% a" T
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
; ?' [+ s5 V+ [  SWDIO_TMS_OUT = bit;
6 o1 F, a" `2 w9 D5 h3 t}
; F$ B2 H5 R& y
3 G) U$ O2 l( y6 P4 T! l+ x' V/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
/ \$ x1 l; @6 k' ^0 W5 u/ r6 _# ?Configure the SWDIO DAP hardware I/O pin to output mode. This function is
" q9 K( ~- M( Y2 Ucalled prior \ref PIN_SWDIO_OUT function calls.  O. P1 {4 K0 K/ n; K: w- r. H
*/% l/ e- B0 a" A+ K) S/ A
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
- k) Q, M' X8 x! R  SWDIO_Output();
8 S! Q) @: T2 j}0 M" J- K& C# g. _
( B; ], ]3 J) N) w: S8 F
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
6 f# [* H7 b0 T. X: GConfigure the SWDIO DAP hardware I/O pin to input mode. This function is
* L5 |% A2 _0 b! scalled prior \ref PIN_SWDIO_IN function calls.
/ n; y$ u2 ]+ u6 a" g*/
! q3 n: w& G3 x__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {/ t( a6 V( p& o3 U* S+ w
  SWDIO_Input();
) j1 D" F: U. A/ J% V$ _" R}' q! V' O1 ~5 Q/ Z; f# K- r

3 {# L2 x2 n3 m# K5 @楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
+ t+ F0 H; p# v4 x即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下& N* ~: `- g3 ^( {0 `: T4 M
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版