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

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

[复制链接]
radio2radio 发布时间:2018-5-31 15:47
赞 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,希望做一个,让复位时给一个低电平复位信号。
" u2 F7 E& a# f8 r
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50' n! P; m- t, O% t' m
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

2 O3 i# i. b( }) B& {我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。& H% Z) P# a, e- A( d* M

' Q( d% [& W3 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:00# ^% k- @: n6 i& B
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

  h' L& ?( U2 L; znRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
/ W" F/ b4 D/ f1 B! f4 ?8 D+ p( ]你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。: k) N3 |; i1 \  f4 R- V

( n, k2 s$ u3 F3 _6 V你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
) i3 N# Q& a2 g7 @& n+ U或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。1 c( B0 E: r% Q1 o
" h4 y) t7 E: F1 ^8 l5 S( q
& l8 F2 h# m% s' A
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?) [5 g) L* v+ I$ J
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
+ w& m9 d/ _3 f, Z+ Q
起点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 H3 S% o/ \: H- v9 P# x$ k; [
/**
& A( p) Q. C/ ~9 d" p7 r+ d5 M' I  ******************************************************************************
" {9 w; D5 H& f4 ?2 B9 v1 D! k  * @file    usb_endp.c4 p8 r1 k4 T/ A
  * @author  MCD Application Team
% ]* h0 j' d8 z9 Q  * @version V4.1.0
5 r  B* c7 L! Z0 x! v  * @date    26-May-20177 }- o5 x8 \! g) \
  * @brief   Endpoint routines& e, e; e9 Z% S5 n7 b7 y9 S
  ******************************************************************************2 ]( E: v9 W( N9 h; d, m
  * @attention4 }. o  h3 H9 @! e( y9 V/ R7 q1 i7 T
  *
8 I7 x# G6 A+ l  g2 |/ x6 K4 P  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>/ G; ?- g+ K% v# m0 E5 V$ f
  *" K& c" \2 r2 t# e: V1 q8 t3 `$ Q
  * Redistribution and use in source and binary forms, with or without modification,# C7 m# S9 s/ G7 L" {; U
  * are permitted provided that the following conditions are met:$ m6 F& w4 S# @* e0 G
  *   1. Redistributions of source code must retain the above copyright notice,1 J9 o' n. C0 q2 p. }
  *      this list of conditions and the following disclaimer.
0 @0 s% t" {9 V# H, u; z- O  *   2. Redistributions in binary form must reproduce the above copyright notice,
$ W5 D5 r& V/ U- o$ H  *      this list of conditions and the following disclaimer in the documentation
, k2 g& C4 u* W6 M* @; E  *      and/or other materials provided with the distribution.4 p, K. Z; w7 H" A8 v' Z* z  M4 l
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
. l) F& ~7 a7 v- y7 m: o! z3 x( ]+ g  *      may be used to endorse or promote products derived from this software
2 g5 T! t( L6 Y6 h% ]) R! g' ^' O  *      without specific prior written permission.4 z5 E: v5 P( t4 J
  *: H& y& b  I7 a6 a) m
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"1 S$ F+ Q: ?, k: d
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* d4 k8 T# b' Y- d) @! |1 T4 d+ Q
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ E- T) [! |" `* ^4 k6 P  `. ^+ V  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
0 a8 u  @7 m$ T9 R) ~3 f; E; L8 w  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
/ \& L7 F  z5 u0 _% A  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
( o( M2 v) q7 u5 t3 b0 D9 W  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ q" J5 @) R+ \- w- ^  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
) _) w" W3 I; I8 A  O  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
6 X4 X( M& i4 K" |, H# N5 ?& w  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ v: g# t" \4 q/ ^  *
& }" ]' T2 a- R  l' l- q  ******************************************************************************
& j# Z4 ~5 E5 V! L4 X1 V: \  */
& ^3 K0 m! ]8 E0 ^9 M
( F! @; q. Z2 P# F0 F/ f
' `( m4 I0 b7 _" D& @6 ^% u/* Includes ------------------------------------------------------------------*/7 |; w" t: v: q# R$ }9 l9 c
#include "hw_config.h"
. F6 ~1 f  w( i/ k#include "usb_lib.h": Y7 e+ y7 D  A+ S) f1 |; K
#include "usb_istr.h"
' S3 @4 C8 q1 G( G* x& w#include "stepper.h"$ a# ]9 ~% G: J' h& o, d  [' X! N. E  F
#include "string.h"
, M6 N& x/ k( i6 H8 _/ ~
, V! [9 r; q& {#include "DAP_config.h"8 r# |, x6 R4 M- k' ~' Q7 X5 |+ R
#include "DAP.h"
0 u0 g4 h& ^% T3 X4 R( t  E# F; n! S2 P: `

; [' M( ]3 B0 [# `( Z" b1 g# Q/* Private typedef -----------------------------------------------------------*/
- x+ q. k+ I$ c  m& w1 w' ^/* Private define ------------------------------------------------------------*/
' Z3 Z9 u4 b7 M% t- N1 F5 W. A1 V/* Private macro -------------------------------------------------------------*/
- ]3 |  t  {0 a  G! z: j/* Private variables ---------------------------------------------------------*/
. s- N4 O* v% Hstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In6 Q) R, d6 l( c  I# |
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
7 \; d$ ]+ U" a! e, ustatic volatile uint16_t USB_RequestCountI;     // Request  Count In
* t$ _# |% ]( b! M2 ]static volatile uint16_t USB_RequestCountO;     // Request  Count Out
2 J- ~1 ~8 X7 |6 J/ j; U9 K7 ?static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag! i, O, i2 r( Y0 ]( ]4 _; d

" ]5 \2 G' |* W! V; e0 K7 c/ rstatic volatile uint16_t USB_ResponseIndexI;    // Response Index In
0 w: U7 `( z& Y" lstatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out& _1 o, r- }# R: Z  |
static volatile uint16_t USB_ResponseCountI;    // Response Count In
( _$ g; Q/ o2 T; |. r" \# V+ Wstatic volatile uint16_t USB_ResponseCountO;    // Response Count Out
) e1 u% h0 L; X: X8 Fstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
# C! K+ t4 p4 @. @) H# }static volatile uint32_t USB_EventFlags;
8 L7 L% w) _# n" Y, K( s: }1 V7 {- s3 R) C* A0 L9 V. V. K
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
8 t0 b3 K/ ]9 G1 ?9 O- `7 p; Mstatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer, R& q4 I& T  ?6 Q, h/ v
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
' ]0 S* E- L- j9 z) x. ]6 ]
7 G( R& m! ]+ c5 @+ R" B1 Q/* Private function prototypes -----------------------------------------------*/- @# }. D; u+ {5 O4 N
/* Private functions ---------------------------------------------------------*/0 H: `& d5 g2 t& H% e( U
/*******************************************************************************
  [9 U- G/ l. _+ O' S8 r) P/ w$ v* Function Name  : EP1_OUT_Callback.. f+ ]$ S: e5 j' q
* Description    : EP1 OUT Callback Routine.1 [2 ^1 O# H8 _# m" X: G
* Input          : None.' A' x+ T, U  X5 `/ B% M8 A
* Output         : None.
- i+ Q' q. I: ?9 i* Return         : None.: n2 |! }. k' ]9 a% }* q% ^
*******************************************************************************/( R. \0 t5 ]' k/ `- {# {- i
void EP1_OUT_Callback(void); l3 o/ D  u3 r( e
{
0 a& q% }) ?$ {9 t+ R0 _        uint16_t n;( t( ~5 n' u8 ~4 M$ u2 W. j7 M

3 b2 \# I7 [! X; M1 E4 b        n = GetEPRxCount(ENDP1);
9 F: s9 P& D4 |0 x, ^        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);0 ~  q2 m1 c: a0 E# W
        if(n !=0){0 n) j  T0 }" u% X# p" M
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
+ P6 b& z5 b$ P/ k$ \5 j+ U                        DAP_TransferAbort = 1U;! Q% p4 i0 r" g- k  g# J. j: ~( S
                } else {$ ~( g( P+ W1 N9 `9 `
                        USB_RequestIndexI++;
8 U) l+ N5 w2 n( J' j/ x; p      if (USB_RequestIndexI == DAP_PACKET_COUNT) {6 G# c% W" B. J0 q/ f9 V4 A
                                USB_RequestIndexI = 0U;% H( I2 y- ?9 w/ m# t7 ~* D
      }! \7 p. s# D0 r3 R8 U
      USB_RequestCountI++;" D- W$ S6 t; M/ O: i
        USB_EventFlags = 0x01;7 r6 F9 G2 b/ x# A
    }  K/ `2 B6 I5 \/ |$ }  D! d
        }        
5 V5 ~* }$ S( q- P, n        // Start reception of next request packet
# D5 i8 I$ M2 @- _( E        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {# Y4 x% v2 Y* j( h- e! I9 _
                SetEPRxStatus(ENDP1, EP_RX_VALID);
' j* B: w+ h  z1 ^% N$ A1 ?$ j        } else {
) x( S0 o. Z8 A/ {1 c: D" a+ s2 R                USB_RequestIdle = 1U;
) M: v( J4 e+ _" d+ Q        }                        
5 A/ ]2 O# c& @: z) M}
1 l' P  V" W0 N) _
2 u9 Y! v; F1 h, b6 w. W/*******************************************************************************% R, a8 J7 v: j, X5 t2 O
* Function Name  : EP2_OUT_Callback., |3 B# Z/ l6 u+ H
* Description    : EP2 OUT Callback Routine.
9 o: S0 l- H1 i& r  h) Y& g* Input          : None.
7 v* M9 h2 u1 `* Output         : None.
" [" U  F* g/ S; Z/ a* Return         : None.
' r) I# G' N% z- W8 X8 N*******************************************************************************/
6 U4 G, s3 X: t; d. t/ ^) Estatic volatile uint32_t TX_n;5 ?5 t- E* S; `# o: w
static uint8_t *pbuf;' A, h( x" a" @( o% G' {+ T. `
void EP2_IN_Callback(void)
4 k1 Z1 F* C! v/ Y{
$ O% A) _# O7 A, e9 C$ V        uint32_t a;
3 v. u* Y+ K8 _8 P* r* S        if(TX_n>0){
1 H8 b* i1 b; e/ }                pbuf+=64;0 z( c* d8 s/ \. T7 b# ~9 Z
                if(TX_n>64){! q% w6 M5 ]9 C8 ^" K9 K
                        a=64;
2 Q/ L' f, f% u& x4 y2 C% |                        TX_n-=64;0 B+ k$ S8 n' |: G
                        
# b4 ^. r: |$ F& ^( J$ t                }else{1 S+ B! Y+ R% m
                        a=TX_n;) W( l- K3 L% o% b- L- g5 s5 B
                        TX_n=0;- ~' N8 z5 h1 b8 ?
                }1 R# t; J; Q2 @/ N! I4 [5 q7 r
                0 _  p, s! ?% [/ I- z4 g; l
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
' w7 i5 |/ k1 s. n9 A! J        SetEPTxCount(ENDP2,a);
5 n8 P$ {7 d5 }% P               
; n8 e5 x1 Y9 N. @" C        SetEPTxValid(ENDP2);( `# B* K4 ^& A( }4 |/ a
        }else{  t# t; ?" x3 \! B" Z9 r
                #if (SWO_STREAM != 0)* N( b. U2 n8 d( W
                SWO_TransferComplete();
1 o. u4 ^9 Z9 j4 Q9 O                #endif
4 K! m# t- V: T/ J1 [1 P. z        }; }& J# l+ C! D- O& ~+ ]" N
}
* ?+ d5 ?! r1 A$ }, i0 m( U% R, U( I$ Y4 L
/*******************************************************************************
% B: b, P8 v- Q. u6 @* R* Function Name  : EP1_IN_Callback./ h* n6 f; j  v. d2 r8 e$ j
* Description    : EP1 IN Callback Routine.
- }' B3 A" `; }; P* Input          : None.9 b2 Y" H3 t# ^2 Q
* Output         : None.5 f+ D( |: G8 u  Y, m, e9 ~  l
* Return         : None.
3 X+ @1 ^% s3 J*******************************************************************************/
0 `. i$ @* h) _, p% P) {void EP1_IN_Callback(void)
( F: B; ~( V- L) N2 z' S$ g; x6 [{" S( l" f0 ?7 b: A7 Y; {
    if (USB_ResponseCountI != USB_ResponseCountO) {0 }* L& Y# s7 q, z& t
      // Load data from response buffer to be sent back7 W4 R1 `" c7 ?( M; y3 M
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
. u& J  e  X$ O; G; k                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
9 c9 H$ H# b2 r* b# r, H0 v! x2 A                        SetEPTxValid(ENDP1);                        
: b) Q( _+ i' o5 l( L      USB_ResponseIndexO++;
$ Q1 m' ^3 q4 ?- |$ b      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {* E& _! N' h& j3 K# h& [' \; R6 L
        USB_ResponseIndexO = 0U;
% u' D& H* }1 P$ J) n      }
( @6 ^6 p+ ]: a  T1 f- A) t      USB_ResponseCountO++;
& u: m. C0 ?% v# ]! e, k. ]1 N    } else {
5 }! x: c! E3 Q4 Q: x      USB_ResponseIdle = 1U;
0 D) v. i( Q% p/ q0 Y    }  
! z9 _8 Q' [9 H& `( U* \}. E: n4 d! h' P& M
. F' v8 ~1 o2 _- W
// Called during USBD_Initialize to initialize the USB HID class instance.
+ V  m! ?6 p$ ?- U; ?void DAP_FIFO_Init(void)
+ g; C7 d* N" O8 ~. f{2 U( t* Z# U# F- k$ k
    // Initialize variables& N' O' g7 D3 P' P
    USB_RequestIndexI  = 0U;% ^' _# Z+ f' X0 ?# j( _
    USB_RequestIndexO  = 0U;
& u2 A/ j* C8 X# k* L; N6 a    USB_RequestCountI  = 0U;  q8 G  |  j7 M) D+ S7 ?
    USB_RequestCountO  = 0U;
, h  e; x8 _$ d0 A6 p4 G    USB_ResponseIndexI = 0U;' M7 S. N+ V+ T2 u2 Y2 S7 \
    USB_ResponseIndexO = 0U;( R* H7 L4 t" H3 v: n7 M; {
    USB_ResponseCountI = 0U;
7 V# x; p0 A$ e( G2 H) g5 u    USB_ResponseCountO = 0U;4 I. _+ \, a: y5 F, H+ c
    USB_ResponseIdle   = 1U;; Z) o( N2 [$ U, ?; A5 e
    USB_EventFlags     = 0U;
$ Z7 [, l# w3 n* D' f/ R6 I7 Z. V; {}
) `, b' `' e+ F$ \1 f
3 j. s) e3 T, D9 e+ @uint8_t DAP_Thread (void) {
& j$ p) w2 S4 m: S" q& G2 Y  uint32_t flags;
( }0 |( m% ~+ j; d7 x& P  uint32_t n;, T0 L4 x+ P5 q5 m  R3 L& M
/ H8 z# r. o9 h8 E) {
  //for (;;) {* P: A; [7 l7 E- K( e
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);+ G1 w1 P; V5 T3 k
                if((USB_EventFlags & 0x81) == 0)9 V3 w6 }# W. ^, ~% L9 h
                {
$ g4 X2 X% U& Q9 S/ Z                        return 0;
7 n9 |) t" a, w: p" h  b                }
4 K  d- h/ X' @8 o' E1 J                USB_EventFlags &= (~0X81);
* {1 ]# L8 I3 ~& T                ; H' r# z1 P/ c  C: }
                                       
$ W. J2 {8 u. D4 [; ?* L6 K. ?    // Process pending requests
& L; O0 @% o& n    while (USB_RequestCountI != USB_RequestCountO) {/ z% R! q' S* `& k5 j4 w
                //if (USB_RequestCountI != USB_RequestCountO) {; _- R' g( _: X, N& ?( p
      // Handle Queue Commands, B6 |/ }* S" e6 b  q" Z
      n = USB_RequestIndexO;9 ~  K0 ]* i1 ~& m2 a* U6 T
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {. C  T* D0 W- E& o- v1 Q% `
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
6 P) f2 d/ b, l) a        USB_Request[n][0] = ID_DAP_ExecuteCommands;) H: R# N' S" K  V
        n++;  e4 G6 C* r$ Q# [  u
        if (n == DAP_PACKET_COUNT) {4 J' o1 A& ^6 L: h
          n = 0U;
. _! S( u1 r2 [$ v        }/ d4 m0 h" H6 t* v2 M
        if (n == USB_RequestIndexI) {
6 X- H- T6 d& A          flags = USB_EventFlags;
+ P# z- a6 n7 a4 G4 j5 Q          if (flags & 0x80U) {5 g) M: @( g' y0 \0 q
            break;
1 \/ Q6 U" C3 C0 H+ \) m3 W! j& C          }! S+ u) J6 H- l. p% x9 Q! C  c
        }. u  ]& M/ M7 L/ Q! B; ?8 x, {
      }3 R* g' h% Q( w- p/ {8 g( I5 ~8 y
! S7 l: z6 Y0 O; r% f* b
      // Execute DAP Command (process request and prepare response)
+ l8 q; ~5 X3 r1 N" }: j      USB_RespSize[USB_ResponseIndexI] =
" e" U9 v! l0 e2 k  P9 G        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);$ B4 Q( e) G, {6 \

8 g0 \3 n8 ?+ g0 R  D9 v1 O! X      // Update Request Index and Count9 \# M1 S  A6 v
      USB_RequestIndexO++;  g* P! S- I7 J
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
2 h5 a" g/ K- P. [. B6 V2 C        USB_RequestIndexO = 0U;$ L4 A' E9 Y6 t- M& t
      }
' c2 @) P/ J- O$ _8 ^" I7 L. f      USB_RequestCountO++;7 a8 X9 r. [2 B! n
. H! @/ t' S3 G+ I2 Y$ R2 I. T" S
      if (USB_RequestIdle) {! w; k' v! j3 y: ^& [# J
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
3 n. f. f( O8 v; \* s2 u          USB_RequestIdle = 0U;. p+ Q7 h5 @& y
          SetEPRxStatus(ENDP1, EP_RX_VALID);
- D0 S: L$ Q4 Q7 W        }
, a! X! G# {: y8 e3 F+ `      }
' u. `+ w% l8 e$ l( @2 k4 @3 |7 m/ n! P5 r) A- h3 M
      // Update Response Index and Count
* ~, V8 W. M, B/ i      USB_ResponseIndexI++;, r: Z- |* k8 t, p5 m2 U
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {( |6 z, x' }# v" g3 g. S
        USB_ResponseIndexI = 0U;
! b8 L% [9 ?: L* W5 o. }' x      }
7 y6 o% D5 |7 P, Q4 m/ t7 C      USB_ResponseCountI++;
9 @) `3 z: t9 G; B2 h7 o) {7 ^1 p4 `# C8 ^8 i( v% E
      if (USB_ResponseIdle) {
+ y4 d" Y, E$ c; i! @2 ]        if (USB_ResponseCountI != USB_ResponseCountO) {
( T: b: J$ R5 M! ]$ \8 k          // Load data from response buffer to be sent back3 |( p! ~5 z1 q# T# k9 I8 m
          n = USB_ResponseIndexO++;. d$ L. E6 V, C
          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
$ L: y! R8 k" _0 B; p+ I) w            USB_ResponseIndexO = 0U;
& B7 ^1 {/ X/ y; a2 u8 X5 e6 Z          }
" ]6 W! h# ?# q& q          USB_ResponseCountO++;6 i2 x( g  \3 G- V& L3 I) G
          USB_ResponseIdle = 0U;/ l) E9 C  s. N! Q! i
          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);# I/ k% d+ Y7 C% C# H; o) y( @0 o
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
! \0 g* t7 H9 X( l$ J                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
. y! m5 x. r" ~5 X1 V' D  ~                                        SetEPTxValid(ENDP1);# r9 c$ G0 N* l' ?+ v3 t
        }  C& S# D1 a. Q' @$ Y0 {3 ~
      }; _' e) T; l/ ]
    }
. M$ j9 ?& X. p& S5 l# Z, c        return 0;
2 g% N. D# M9 H. h}1 A/ P9 b( Q; M

; J4 j) p3 i  ?3 k- E// SWO Data Queue Transfer
7 i& p& l  \9 w2 o- }//   buf:    pointer to buffer with data; P  V4 z6 R) }  Y# ~
//   num:    number of bytes to transfer9 @- [9 c/ F) A0 m8 t+ D7 m
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
- B+ r2 J5 e- a9 Y  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
/ L9 f  L0 `7 W) j, k0 V& g        uint32_t a;
7 H4 f& P9 @6 e4 K        
0 b0 t( J* q0 r8 @# s! H        if(num>64)  _" m: h- b; p/ F
        {
9 ]+ H* Y4 t8 ?  [. r: k                a=64;
- }% _5 H! }+ t8 i' _/ L3 r                TX_n=num-64;
4 I" ~+ w) `7 l( F' y2 I& J                pbuf=buf;+ I" m( X* e3 `: B2 W: F% J5 S
6 ?5 z5 j- a, ^9 ~4 ~
        }else {" K* j; z. K7 [: e# J) @6 z
                a=num;
8 z' H6 C1 `0 ^: X, j5 n' G5 f5 P                TX_n=0;) H  z' c+ h& q+ @* M7 T
        }
7 ?- o6 i6 r4 J, ~1 I. o4 T        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);8 M' y, e. b$ P( i' Z
        SetEPTxCount(ENDP2,a);
7 m. `: r4 p! F/ ~; t- s7 A        SetEPTxValid(ENDP2);
4 r( N$ @6 v9 `+ Q2 q! |: e# \: ~}7 u$ |! [; u7 N5 D" y

* t  k( l- _2 T// SWO Data Abort Transfer4 B: L4 |7 k; B( N  w( ^$ M0 C+ L
void SWO_AbortTransfer (void) {: G' \! C2 b: Q4 r8 l
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
+ F- _# B- s; ?: A        //SetEPTxStatus(ENDP2, EP_TX_NAK);6 y/ c( z/ V% ^6 m6 f1 z0 ~) k
        SetEPTxStatus(ENDP2, EP_TX_DIS);# L: n8 l9 L1 c5 f( ^: u( p" S
        SetEPTxCount(ENDP2,0);
. o. _3 g' P3 d8 ?0 V. s        //TX_n=0;
) ?& C. d% B5 Z. a}
/ C: `( X+ y, @- P" j4 p9 h6 Z/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
3 N" h6 M( x) u  A. |
2 l/ ?' E5 ^  d+ B" _. @移植大概是这样的,利用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% W$ f/ L) e: p  bDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了
" m, ?  \: h- ~& T* _! ]__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {; }) ^% z. W% n/ D; g
  return (DWT->CYCCNT);6 T. e  p3 s+ a1 h- H) V
}$ a( z1 ]6 I( R: X+ O

+ U4 F, h' ^! L! P4 Nvoid DWT_Init(void), e& K( F2 I  m. C7 D6 S% Y
{" `9 u- _* E( s
    /* 使能DWT外设 */3 B2 m% p' I/ g1 `! d# A
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                ! M( o* |, F: O' F# w2 ?! y

; L; e5 r) Q0 d/ e, f! B6 }    /* DWT CYCCNT寄存器计数清0 */
9 J4 ^' u: V' w0 H$ e$ @, j    DWT->CYCCNT = (uint32_t)0u;
3 [6 ]" o$ J8 g3 m: B) X4 H) ?
* D2 Y2 v- y" e- k1 F  {    /* 使能Cortex-M DWT CYCCNT寄存器 */7 o; U7 O$ ~) }* C& s
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
" i: \9 @: J; Y3 ]2 I9 d}, P# x" h/ a/ M$ P; X+ _$ X2 i
        , N& D% U9 V/ T! J, `$ {9 q& P

1 e( F& ]: g5 H4 K然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
7 V0 W/ `' U5 A0 _$ l+ p- r# x* M2 W6 Z
然后改为使用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不香么?
% r$ D! F8 V" w+ g1 c声明这个变量static volatile uint32_t SWO_EventFlags=0;
$ C- `/ `$ s3 `, z) [$ Z/ l在SWO里每一处调用osThreadFlagsSet的地方都改为如:* d  A8 w$ p$ b  }$ J  n
//osThreadFlagsSet(SWO_ThreadId, 1U);
. [3 h; ]* x+ JSWO_EventFlags = 1U;5 Y4 o7 `* s- J% q
) z  c& p5 g/ W7 O
: J; R, H5 \7 j: c0 E
// SWO Thread
2 x, Q* ]+ W7 u0 u7 P- l# _+ B/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
# g  K" N2 J4 v! V7 s- e* e  //uint32_t timeout;2 i$ X9 q" \3 h2 d3 v& j, I$ b4 f
  uint32_t flags;6 t) ^& V! ~+ `# S' ^0 ^
  uint32_t count;$ u" N- t* G7 D3 h/ z
  uint32_t index;
7 W; n0 W4 J- a6 J  i3 C  uint32_t i, n;/ w/ S3 m  I; X+ ^# Q2 ^0 D
  //(void)   argument;' |1 k# R# c9 c8 M- c
! u" K( C% Q/ l
  //timeout = osWaitForever;( D$ m. W5 @% J
9 K" G4 S9 I5 s2 W
  //for (;;) {6 S' @. D# ~0 v. F% J7 D9 o
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
) s3 w! n7 W; F. k5 k1 w; Q                if((SWO_EventFlags & 0x01)==0)return 0;
2 A, j  Q. i4 [# P5 u         3 z* j8 c. s! v
                flags = SWO_EventFlags;
+ p$ N* s4 @6 F3 j  T1 ?5 p! b                SWO_EventFlags = 0U; # X: q; p; j5 r) y1 U# a% T
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
) j" Z2 E: h" v      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子2 e3 e* ?: v+ D2 C
                        ;. ~  I; R$ @- q. c+ U, j2 P; x
    } else {6 h0 r0 |& J! P7 C
      //timeout = osWaitForever;) ]7 z; ]; D. c9 s
      flags   = osFlagsErrorTimeout;4 I; O5 A0 }2 p2 @4 k
    }
, ~! W$ z" H: K5 J7 f$ |/ E6 a    if (TransferBusy == 0U) {3 I/ U& @# }! M3 @7 c$ G  R6 W; ]( x
      count = GetTraceCount();+ x0 S. ?( k& H; w% Y% r0 Y
      if (count != 0U) {
4 r) K% }4 |) r/ m, _% `: q        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
- h1 A: N, t! a2 d        n = SWO_BUFFER_SIZE - index;! L" J  x+ u6 J. ]' i6 e
        if (count > n) {+ b, Y$ Z  x  `
          count = n;/ W1 w' b5 s6 j' x3 l
                                       
3 k3 ]: D% z. V4 B  U* {) m7 w) D        }
, D+ T3 B- W* m8 G* A$ R5 c                                if(count>USB_BLOCK_SIZE)
1 i5 K  [4 q  K9 I: H1 h1 h- E( K                                        count=USB_BLOCK_SIZE;0 z8 @+ k2 d; h
        if (flags != osFlagsErrorTimeout) {+ a3 C$ b  h+ ^7 ]4 p
          i = index & (USB_BLOCK_SIZE - 1U);: D4 ?7 v5 c+ L2 `1 e
          if (i == 0U) {, t# v; P6 N: V- r
            count &= ~(USB_BLOCK_SIZE - 1U);
& C1 w% m3 s$ I2 f1 ?          } else {
, M9 N9 K7 X; t            n = USB_BLOCK_SIZE - i;2 j" p2 Z9 e9 p% \
            if (count >= n) {# U5 I' m/ z) N6 {" }" Y8 W, _
              count = n;
' D( [; |1 C, r- \8 R4 \5 R            } else {4 D: \5 a5 v0 {* A  q
              count = 0U;; R+ |' b6 o( s/ i) h. J$ r4 u
            }
1 p* a% z; }; x; S: V          }; l- Y8 p- P; ?  g: `
        }. y; A$ N% p0 ~2 F
        if (count != 0U) {
8 @0 B: m7 z2 Z  e( ~/ C  b! s( U          TransferSize = count;
) E* B9 r% m! C- r) Z8 b5 F. Q& J          TransferBusy = 1U;
4 c3 K) `1 ~3 ^* j8 h          SWO_QueueTransfer(&TraceBuf[index], count);+ \# F/ x0 k# D* A& |) h- Q* _# y- N
        }
" _- R' F2 Q  r0 m# X. e      }, V. e5 t& h: m4 i' e4 b3 y
    }
& ?; L4 T: @% D' Q  //}/ S, i' D$ n( `# ]7 ?% ^
                return 0;! M' O3 `# g( h5 o3 I
}: j. Y9 Q0 k& `: x
利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.5 W7 ^/ X1 a& s3 W: q
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).. a. w% Z5 j7 ^4 N) a0 e
static volatile uint32_t SWO_EventFlags=0;
( X2 M0 s+ z$ n" G2 i2 f8 dstatic volatile uint32_t timeout=osWaitForever;6 D4 t& x5 R4 t: l, D
static volatile uint32_t timeWait;
' @$ Z4 S5 j# |; |8 J& C函数改为这样: A4 O8 D7 @- [" X- A; a9 i# K$ i& t
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {4 ]- Z7 X1 `8 v8 z! _, n. e" z& T
  //uint32_t timeout;
! U5 }7 O% P$ `7 q6 l) l- ]  uint32_t flags;
# D& u  E- @4 R: a0 e  uint32_t count;1 `3 V4 G7 H1 A5 J* q, q- x
  uint32_t index;
1 r; e& A# o3 F  uint32_t i, n;' v7 Y  A$ ^) D3 Y
  //(void)   argument;
& f$ K- l) P3 d& j5 f
! h: Z' z8 z0 g+ L6 Q0 M9 I  //timeout = osWaitForever;, ?, {: V& U- n# f) M4 j
; G# C0 S0 {2 F5 t9 r! P
  //for (;;) {5 ?$ j: W6 F& j# ?9 ^0 E1 @
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);# k% J" Z% k" O6 a4 V* O! r
                if((SWO_EventFlags & 0x01)==0)) i5 o0 b8 e: z% k; A* o9 u
                {0 L9 i  J: y) @6 R( {6 X
                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
% m4 C( [' U( J                        return 0;
( Y$ s, d: W! |, p' A                        
+ y. [3 A0 ~; U4 H  v' M% P) k                }, i6 T& Y: K' U; q0 g8 L
         
: |* c. y) f# b: V9 c. r0 D$ f9 c                flags = SWO_EventFlags;2 s2 Z* \2 ]* q" ?
                SWO_EventFlags = 0U;
6 E% X: f, [+ n4 B+ |1 o    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {, Z5 }; p0 k! c+ @
      timeout = SWO_STREAM_TIMEOUT;( R! U3 i, i6 Y# m2 {# k
      timeWait=DWT->CYCCNT;
" D# b0 G4 v3 b! t9 p6 k    } else {1 L$ A# s9 k9 z( b
      timeout = osWaitForever;3 p/ `$ B. l# D2 e
      flags   = osFlagsErrorTimeout;
; y% E8 h+ n7 Q3 O& p    }& f% N6 J" ^$ H7 F6 M& j
    if (TransferBusy == 0U) {6 v6 {% e4 c5 T! R# I
      count = GetTraceCount();; S- j0 u- k& R* N7 t/ h- p
      if (count != 0U) {1 D; i  f( t% J
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);' E- {4 [8 P) m5 c% y8 |
        n = SWO_BUFFER_SIZE - index;6 g. M3 X# z0 R* U7 g7 z9 z
        if (count > n) {
' h0 {. U  ?: I! c7 M- A          count = n;9 F1 z8 `' c  L& C2 ~' `
                                        1 g0 s1 a7 A" `, O9 H$ A8 {
        }% w, l8 X% K; u
                                if(count>USB_BLOCK_SIZE)
# Y' {: F$ _; j                                        count=USB_BLOCK_SIZE;- H4 W& r% K+ f
        if (flags != osFlagsErrorTimeout) {
5 |+ O3 t2 {7 }; l          i = index & (USB_BLOCK_SIZE - 1U);5 v/ `; `3 q* k3 e6 R; d5 X
          if (i == 0U) {
9 U" P3 D" k% @4 [+ V            count &= ~(USB_BLOCK_SIZE - 1U);8 t+ A' y3 `* ?) k
          } else {0 q3 q2 B8 V) @8 B0 w2 f1 e
            n = USB_BLOCK_SIZE - i;
# B7 y0 |$ o* ]8 `            if (count >= n) {5 {% Z& ?+ G4 e7 `  g, V' n
              count = n;
4 n" d+ e4 s7 S* A* T2 a* Y            } else {8 |7 I# b& U& z  i
              count = 0U;3 }7 Q$ p2 z: B" _" d
            }, K% z- _! I7 r8 h0 v& a3 B
          }
* o+ i7 X; c5 B* e. n' U        }
/ h0 G  {* f$ C" G5 x( \; L4 X        if (count != 0U) {
3 [1 x/ Q* Q% y          TransferSize = count;7 p1 ]1 z2 w+ z2 l( R
          TransferBusy = 1U;, R2 t" ]; g- P
          SWO_QueueTransfer(&TraceBuf[index], count);
) i/ M( [* s3 S7 Z. |; e$ w        }: U+ r4 P0 d' w3 f1 ^. R9 A
      }
3 z' Q2 c- \( l; f2 i1 p    }
% l- X! Q. J6 P7 d  //}5 m, w, |# M$ j. n1 P. B4 t' N9 N/ b. f
                return 0;0 x/ \0 Q& \0 J/ d
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了- N& m5 |) T/ w  v& D7 W5 |
' `" L/ y+ b% V8 T
CDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率! C' d% ]- D7 h; U" l; ^
: \. A/ y: A9 a& A& Y/ H

, [9 n+ c; A4 J8 g4 Kint main(void)
6 \) G4 o' k' h7 F{! P% R# S6 [/ ]. e5 w2 M
  DWT_Init();' c: C4 q  D4 v4 l4 t
        DAP_Setup();
0 n, V0 _1 r/ [* F7 P8 ^5 ^9 z$ H  USB_Interrupts_Config();
3 w' R1 k* x/ d6 N4 \  Set_USBClock();
5 d2 w8 h# [: C/ U( b  USB_Init();6 d. [6 l3 c! g. h+ o$ \
        //TIM3_Init(35999,0);
- P7 h# }5 f. j2 ?3 t; J* ?        //TIM_Cmd(TIM3,ENABLE);
' h$ u  v) A* S6 {        
4 n1 ^  m" A) {( w        
! y. J: y7 C+ m* p- C. n  while (1)
7 C4 s5 x1 u8 r# |  {' J1 v8 R* v5 W8 y( D$ z' M& I
                DAP_Thread();
$ L6 n3 a6 j; [                #if (SWO_STREAM != 0)% [2 n1 F3 w; P; M2 F; _
                SWO_Thread();
6 N3 e0 N' A& K' A( F0 J5 C* i- {                #endif
6 s) h5 K) u6 n; r  }
) x, m# \& i/ ^) }0 w8 K- {}
2 G0 `: u/ o% H$ z/ c6 u: N3 d: D, h1 G/ j, r. M: O4 a" j
对于DAP_config.h的IO配置我是这样弄的% U- h7 V' i  y" h( _  H  N5 \& o7 I
///@}
& e1 |" a* a5 F" U# J3 N6 _// Debug Port I/O Pins+ E- e* R2 m3 |2 x
1 q; ^. r" M1 `5 @
// SWCLK/TCK Pin                GPIOA[6]# [+ n4 X6 B4 d$ D
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
; K5 f0 @6 B  I* `9 V. T#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118  i6 v1 H! Q3 h  b( Z; [" f6 r

' I1 j" K! Q' H4 V: {// SWDIO/TMS Pin                GPIOA[7]; i* e( }9 r) `( i+ S
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
# e/ D# z% F, _+ w+ _& y. m#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C/ N; V' I/ w2 u+ H. }

1 g; c0 k% s' ^, J// SWDIO Output Enable Pin      GPIOA[7]
' L% a1 y  x8 W. B6 Q#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
  s) H  w+ j8 ^; F$ }                                                                                                                                *(uint32_t*)0x42210070 = 1; \1 R! c8 [9 o0 s+ R3 p& `  v
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
* I. i$ l$ `- F6 S* O                                                                                                                                *(uint32_t*)0x42210078 = 0; \
2 o! l3 h8 s4 h0 e                                                                                                                                *(uint32_t*)0x4221007C = 0;}
; B# ^' F5 u) t0 g6 x" _0 P8 Z% `" P4 q
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \- S6 P$ R3 G: G- [3 h/ u
                                                                                                                                *(uint32_t*)0x42210070 = 0; \. V0 j: i9 T. P) @! \
                                                                                                                                *(uint32_t*)0x42210074 = 0; \
3 Z( ^" [. a$ B( X/ y                                                                                                                                *(uint32_t*)0x42210078 = 0; \4 v3 \2 }3 x6 K" ?
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
, S% c/ r2 ?, ]. C
- T7 O, A- }1 M+ J/ W// TDI Pin                      GPIOA[8]
5 u& G. W% R9 B7 Z- {7 x3 m#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
% Z9 b2 y6 W7 e4 n  x% G#define TDI_IN                                     *(volatile uint32_t*)0x42210120" e" U  D7 v2 d
" G( \) `1 E: w
// TDO Pin                      GPIOA[10]
, v2 Z% V- F1 G; {  S4 P) `1 {#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
  N' g% Q, O7 D! i3 [#define TDO_IN                                     *(volatile uint32_t*)0x422101280 J7 P# b: J% u- @- ^( v/ M  K

0 s  _$ e# B  y& @8 i// nTRST Pin                    GPIOB[3]2 P; N' j5 X, i: B/ r2 g( c) [
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C$ M# ]! r! m. B+ r, ~' l8 ]
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C: H' T6 F* L( a: [

1 Y- g4 i$ Z2 ^- y5 l& X2 K, C// nRESET Pin                   GPIOB[4]
4 Y* g) C3 v* \( Y9 _' s#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
& }; L. q1 m4 S8 d8 t#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
# m$ R+ E7 _6 G: F
+ o9 ^' B! U( y; `& p8 O// nRESET Output Enable Pin     GPIOB[4]
$ n+ V3 V9 o. [, k9 e) F( L/ A: c#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \1 N: z- b  Q9 e5 [# Z( `" L4 Y
                                                                                                                                *(uint32_t*)0x42218040 = 1; \) K; M4 {9 O. m& G2 m1 {: D* r( X
                                                                                                                                *(uint32_t*)0x42218044 = 1; \
8 X7 G9 ?- N: Q7 `$ l8 Z0 E                                                                                                                                *(uint32_t*)0x42218048 = 0; \$ j& \! T( `. m6 u' ~" b0 ^
                                                                                                                                *(uint32_t*)0x4221804C = 0; }
8 [* n& K+ M( ^. k- Q0 q
# D  p+ N  W! W1 v* W( a#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \! u- B. s/ K; F
                                                                                                                                *(uint32_t*)0x42218040 = 0; \
  A6 K3 |0 @( X! ~7 Q6 |9 w                                                                                                                                *(uint32_t*)0x42218044 = 0; \! V' d5 H/ \6 `. c4 I
                                                                                                                                *(uint32_t*)0x42218048 = 0;\/ |/ t- ~$ R; ?5 d2 c) C
                                                                                                                                *(uint32_t*)0x4221804C = 1; }$ q# J4 _8 s8 ~

" f- K: G# c0 l/ n2 n! ^
* A$ Q  b6 W: Q1 r2 Q/ v// Debug Unit LEDs+ F# J; i1 J( ?( M& Y+ Z8 |  l

: y% s9 E6 w5 G3 L// Connected LED                GPIOC[13]' y/ V' D1 g4 N& r
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
$ q  H: L) Z0 e' J' E+ @/ j  {, E#define LED_IN                                                       *(volatile uint32_t*)0x422201346 |4 S$ |/ E5 D- L

  q/ G! m' ]' ~6 F/ y( u#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
* E. ?0 s7 y5 h9 D; C                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
/ |. ^+ m8 T4 b: ]% D                                                                                                                                *(uint32_t*)0x422200D4 = 0; \) `3 t, ?0 @" x: v2 M+ q
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
% R8 C' x9 w# L/ {- V5 X# i& t% C                                                                                                                                *(uint32_t*)0x422200DC = 1; }' o& C7 b2 U+ X( F; q
// Target Running LED           Not available
/ _$ Y$ L+ i, O# @4 r* x9 L- _, W1 p
// SWCLK/TCK I/O pin -------------------------------------
4 w4 I/ N$ A, [" i1 y- \/ @( Z9 Q3 b
/** SWCLK/TCK I/O pin: Get Input.
  S. ?4 z/ N3 t% |. N\return Current status of the SWCLK/TCK DAP hardware I/O pin.( \$ i! s; |2 c5 M9 X4 M% o, A7 w
*/. z+ Y- i  Q+ N8 n/ c
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
& {1 k1 x- l) E* Q0 B) {3 S  return (SWCLK_TCK_IN);4 ]2 E7 L: ?; p2 f# d% O- q5 |
}
" U! y8 C0 p  ]/ L2 D) v9 L
$ ]+ E( Q, E( U: c" l& F/** SWCLK/TCK I/O pin: Set Output to High.
0 R- |1 j4 Q7 {% }Set the SWCLK/TCK DAP hardware I/O pin to high level.
. [0 v% K- ^& p9 W*/
% e; b" }* I# V$ @" n; D0 N9 B__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {
( o- s$ C4 A# @1 l  SWCLK_TCK_OUT = 1;
4 G& Q% N" f* C, ?/ l5 v6 X}
/ e/ f8 W/ W+ K8 d* F
' n: S" }) @6 p( p/** SWCLK/TCK I/O pin: Set Output to Low.- d' D8 y3 B# V0 D+ n) [* n
Set the SWCLK/TCK DAP hardware I/O pin to low level.* E0 a  O  [; P8 z  G( l
*/
# o3 W! z* F" B__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {. w) y& d4 }4 n
  SWCLK_TCK_OUT = 0;
5 `2 _1 M. C% L4 o8 b- s}
5 b- ?* d2 J- J/ q8 L# o3 i7 Q$ A$ @5 @) j! d; R% j* k

. _& a1 ?" j3 I& V! n5 @, {% j// SWDIO/TMS Pin I/O --------------------------------------
! \; T$ t4 Y& Y) C; G
5 V. }' i% X+ o/** SWDIO/TMS I/O pin: Get Input.
! M  q  E$ u+ T0 S  S# t\return Current status of the SWDIO/TMS DAP hardware I/O pin.
! B& f* ]: a! M4 B; q, ?*/. Y, D( b, P4 G1 _9 k# F: q: ]
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
8 s4 C$ k( Q" K2 U* h2 }- \/ H1 X  return (SWDIO_TMS_IN);
$ f* Q1 g! Z0 l/ y7 h}
% K* s" N* ^$ T1 ^; L& A1 ]  x8 {' E# t
/** SWDIO/TMS I/O pin: Set Output to High.3 \0 B+ _( a4 U) b5 @" t) d- ^
Set the SWDIO/TMS DAP hardware I/O pin to high level.) N) b' x6 K: v) h4 o* O$ Q
*/
( _9 Q2 o0 L/ G' B* D$ ~8 l__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {2 }! e, ~$ @/ [4 W& b
  SWDIO_TMS_OUT = 1;* M6 u6 u- }; ~( \
}
+ l7 _* l, Q( A/ P* z, H
6 {- X! [3 S% Y, p4 _2 U. [/** SWDIO/TMS I/O pin: Set Output to Low.
, z/ i& x: j5 Y$ CSet the SWDIO/TMS DAP hardware I/O pin to low level.
, ^! n. Y& U/ r6 `*/! V' y3 |9 Z4 Y' C  i7 ^) H
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {, f& F2 k1 Q5 C3 A$ u7 s3 I( S+ @
  SWDIO_TMS_OUT = 0;
1 u& D6 W& O3 t7 ?}$ I. ]" d, ?. _) U( M9 a6 r5 {
) c2 g# }8 J0 J* b( a+ B
/** SWDIO I/O pin: Get Input (used in SWD mode only)." R  c* O1 j6 S7 S! b
\return Current status of the SWDIO DAP hardware I/O pin.& w% z8 R# m1 E- c  @% z
*/5 ?, }; ~9 I$ q' y! U2 K, @! J" _
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
% f, C  [- m! Z  R4 g: b) Z  return (SWDIO_TMS_IN);8 ?& I% a/ K0 p# k
}
1 n3 e# z' c& L% ~. J3 s& X- K5 s/ G9 `7 k
/** SWDIO I/O pin: Set Output (used in SWD mode only).% u; G; X: z; J( W1 \
\param bit Output value for the SWDIO DAP hardware I/O pin.
& |) Q0 i$ [# O" G5 l*/3 a2 R- |/ y% F7 P' d, |
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {2 t3 G9 ?) F+ D9 R
  SWDIO_TMS_OUT = bit;0 u6 r9 e+ V. L  J
}: a4 `6 g+ g2 s/ l' V; r
) \& G' \& D  y! |6 p% i
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
' c6 o  i3 Z, ]. D0 t: o& DConfigure the SWDIO DAP hardware I/O pin to output mode. This function is
7 i0 o* v2 |( W# J$ P* n1 tcalled prior \ref PIN_SWDIO_OUT function calls.
1 ^# F9 t! h% R5 U5 V; l% N5 V*/  G& F! B! X. o' r/ u( o) i' t
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {: Y% |9 @: G4 \  x2 |& v. p
  SWDIO_Output();! Y( G" d7 Z& @
}/ u' j# j4 e/ V$ [/ v+ @
+ c* K/ B' A4 M6 V$ `. V8 y
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only)." {0 i! M5 R/ x! B1 \
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
# M3 v7 U: q, s0 i5 x& R: l4 |called prior \ref PIN_SWDIO_IN function calls.6 c. m& b) D- F0 M+ G) z
*/
% A1 ]+ R+ c$ J__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
# s9 l8 @6 H# u! ~  SWDIO_Input();2 g2 E+ l6 G4 t4 P. f8 }" J8 C0 o/ F) P
}
( h8 @! E/ N) D& s' B' m
$ o' j& Z, m' K# w. K: G6 C, b3 z7 ?楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
6 m  m4 n6 u$ h+ \( H% N即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
# _- n0 F; a9 K8 k4 q9 t4 H
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似技术帖

官网相关资源

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