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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。0 Q3 t; t4 L$ R
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
4 V% c" C$ A: k5 S4 N. i7 X1 J, R除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
* N' R* {- T. K7 e  U- w
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。' O1 J! T! \% P0 i0 x
+ |" F! U: T+ k, s5 k
软件复位是另外一种情况,需要向目标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
) ]: \& t% k% r+ x8 Z可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
8 F8 K. }1 B" x
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。( j$ d" d$ x$ D' E+ M  p
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。
( L& f( U$ \9 f! l  u3 [9 E+ Z
+ d/ b% r( ?* \( n; J9 K你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
4 `8 ^+ w6 i7 X* D, c* W9 c, D或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。6 v: @& v' B/ X) k

' Y5 s5 O6 |3 V6 U! }; ~; p" ~; s$ Y" @
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
) C% d0 ^: f( ]* k, w9 u1 t
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap + m1 @" r% p- E( Z
起点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系统,轮询执行3 Q! X' y- S4 ]: G
/**
# x- q+ b/ N0 c8 Q  ******************************************************************************
3 N" ^/ O5 g" S# Z" b$ |! ~  * @file    usb_endp.c2 P; Z' C/ @' O' k
  * @author  MCD Application Team9 D% j$ {$ @- F" z4 D! V! [
  * @version V4.1.08 a8 b) K$ e; s0 d/ K% b( S% R
  * @date    26-May-2017+ A3 T0 }5 R( d1 w$ v
  * @brief   Endpoint routines
8 X: l5 d! h# Q6 u$ g+ `  ******************************************************************************
5 E$ H; a4 u! a7 U  * @attention
% V9 u  }, V( |/ T" I9 R  *
+ v1 r( y7 j' I* |2 U1 W0 w  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>$ M- ]  \  B# k, e4 ]- x3 \9 Y1 q3 \( W
  *
- F3 W$ F% f+ s: c  * Redistribution and use in source and binary forms, with or without modification,! Z! x: s3 T+ H4 [. {" A5 v: ]
  * are permitted provided that the following conditions are met:2 d- Z  w1 ?) o4 _' E6 e) s
  *   1. Redistributions of source code must retain the above copyright notice,
' z- J* t# \; z4 s4 j  *      this list of conditions and the following disclaimer.
' Q1 g) N- |! O1 b9 t! y% L  *   2. Redistributions in binary form must reproduce the above copyright notice,
; I" ^7 k& _( h% s/ l/ V& i  P  *      this list of conditions and the following disclaimer in the documentation" L% R7 x" O+ F( h) E6 `" \
  *      and/or other materials provided with the distribution.( M& K1 c! q* E! M% ?- }% k) c. V
  *   3. Neither the name of STMicroelectronics nor the names of its contributors" O' \; C+ c  t! T5 ~
  *      may be used to endorse or promote products derived from this software
( o$ Z. t% l, ~4 T: W  *      without specific prior written permission.; Z4 N4 d( F" l8 k
  ** ^# d4 o- q9 T: g( m
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"7 y" ~3 u% S5 N5 L+ ?
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! n& Y! g+ U) x5 [+ \1 S; g  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE) l: ]2 t7 a; `: b8 _4 F
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ m8 p  e  d# b, l6 U4 K  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL7 L3 _; l4 C; O& m: d8 A: q) Q
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR) g$ W: e2 {9 R' B4 \
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
( G) v7 e9 A( X" J  X% y  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7 x! N( m( Y/ @; Y% J  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE9 Z& \% Z/ I1 G0 ~3 h' q& p$ G& c) s/ Z
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4 L2 N6 z& T5 c  *8 u1 s# ]; I9 {
  ******************************************************************************( _, q* T8 j/ r! ~* A4 W2 C
  */0 J( v% f, b* T

& n4 {+ C8 z# k0 G; x
8 h3 G7 y4 ~/ p8 f, g/* Includes ------------------------------------------------------------------*/
& T# T6 ~% e: @$ D. A8 |#include "hw_config.h"
$ p$ k1 I1 B8 d# w8 E1 X" h; y#include "usb_lib.h", Y/ `9 v1 B5 l8 d5 B+ J, `. n
#include "usb_istr.h", K. X  X; F7 V& q; {4 Y& }
#include "stepper.h"
7 E& d& a0 `+ l#include "string.h". A7 s6 @. c/ O; l7 l: p

8 ?+ R  Z4 j" l7 a/ k! _0 r2 y#include "DAP_config.h"
8 R) ?# V6 b4 {$ \( T#include "DAP.h"( t: q  p4 `3 r( I0 F; Z

8 N# f( t# I/ `3 R# h" f$ s0 H/ ?: p5 Y; l  R- S
/* Private typedef -----------------------------------------------------------*/
5 V6 S& y' ^& D. R/* Private define ------------------------------------------------------------*/
$ ]4 t/ b( }2 [7 d  D! w2 |/* Private macro -------------------------------------------------------------*/
( h" I* M" ^( ^$ b! k/* Private variables ---------------------------------------------------------*/
. R) I4 n2 T$ X4 z8 astatic volatile uint16_t USB_RequestIndexI;     // Request  Index In
( k# U* f" l% j5 z# nstatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out( O! P$ M( c. Y
static volatile uint16_t USB_RequestCountI;     // Request  Count In1 n* e8 ^' [% c# r8 f, p
static volatile uint16_t USB_RequestCountO;     // Request  Count Out
9 i( x3 d0 A' Y4 Sstatic volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag7 w+ V4 D7 X% \9 V2 L3 n

# w+ k( N: F) r1 Y, u7 s+ Mstatic volatile uint16_t USB_ResponseIndexI;    // Response Index In5 a7 i, c" i" w$ R
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out
9 Z5 L4 X2 W/ u, q) _static volatile uint16_t USB_ResponseCountI;    // Response Count In
7 M8 G1 ]6 m1 Kstatic volatile uint16_t USB_ResponseCountO;    // Response Count Out
; x. ~" O( X+ D1 J5 b$ Jstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag0 V" [. P9 |: x; ^- ~' E
static volatile uint32_t USB_EventFlags;5 w7 D) C  J5 f- x( m" g  l3 T
' u& w, i% L7 ?  N9 `- _& a
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
2 E; j9 n) b  P& Y& istatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
# p6 \2 Z. `" |, b; M* A1 kstatic uint16_t USB_RespSize[DAP_PACKET_COUNT];- g( e) @0 z8 a  m- G; k0 c8 x$ Y
$ G# i1 N0 ^, y5 R4 V: g
/* Private function prototypes -----------------------------------------------*/. R4 d3 Q  ?) Z5 u
/* Private functions ---------------------------------------------------------*/) b% ~1 y$ E" @0 O- m+ I
/*******************************************************************************2 {4 A4 t! ^/ R$ [
* Function Name  : EP1_OUT_Callback.
+ Q4 I7 ?% Z( q* q9 T: L* Description    : EP1 OUT Callback Routine.
9 n: T* p! V) C; A+ f3 H* Input          : None.
( s7 K6 {: c% f& d* Output         : None.& k9 {. Q6 F: h$ A$ a
* Return         : None./ O% B# a. o3 r' R7 q$ ?* h4 ?! M8 O
*******************************************************************************/% o* ]! c/ F, U) c  n8 R% G6 a& W! B
void EP1_OUT_Callback(void)6 {* i" I" |6 u( e
{" J$ J% I$ m/ R
        uint16_t n;
$ B! y4 D- r7 M
& T6 J( M- D9 b  w7 B( p        n = GetEPRxCount(ENDP1);
) D- ^8 r! @( l+ I        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
3 n1 \! m7 z- W9 c( b( H& [        if(n !=0){/ A6 c) V$ f( A$ r; R- j& y
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
5 t# ~( z6 v9 T1 m! }0 J                        DAP_TransferAbort = 1U;0 h1 i) M+ K3 ?, k, p: Z
                } else {
) L3 ^4 R, q" g1 J) E- l# ~$ R/ p6 @                        USB_RequestIndexI++;
8 d8 }: f- D5 v5 d; \7 H      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
, x& q  v- d# u5 d/ k+ Z( c                                USB_RequestIndexI = 0U;: g3 l. y8 r5 _/ a/ j
      }, J& ?; v0 q# g
      USB_RequestCountI++;
# x& @/ W% \% O5 P% U        USB_EventFlags = 0x01;
* q# h' g! k. P2 C3 S% E    }. r& F. t, }: n  J
        }        8 a9 n8 F& B% ?* Y/ C2 N
        // Start reception of next request packet/ @: l/ G" R0 {5 ?4 d
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
* B( \; L, w6 |" \                SetEPRxStatus(ENDP1, EP_RX_VALID);% j4 N8 J, j2 |' p+ V& |( X  ^
        } else {( i5 t6 u3 ^( y) z
                USB_RequestIdle = 1U;
8 ?! \, x* s; V) c1 i- d! e# x        }                        
0 }# q2 k$ m! [- S}8 z- v5 d7 g5 b, S; j
, V8 c$ C" E. N* n
/*******************************************************************************
" f: s( ~& U. V6 I7 x: c- r  q. F6 _* Function Name  : EP2_OUT_Callback.
/ v# P: `+ C0 q( [* Description    : EP2 OUT Callback Routine.
% q# k0 |6 O) N% T2 F* Input          : None.
' R0 H4 y% n5 p. z" C* Output         : None.( b6 f) s. i8 _  L3 E; w
* Return         : None.8 _2 C- _9 Y- M9 N7 S
*******************************************************************************/
, e1 h. \* `6 q' ^' tstatic volatile uint32_t TX_n;3 S1 g7 Z( ^8 p3 O
static uint8_t *pbuf;# H  c" C/ v( F0 p* Y4 g$ Y
void EP2_IN_Callback(void)
, T) D9 _! {. s8 K0 d{8 X2 A) `, Y9 l0 G, q9 ?1 r
        uint32_t a;
8 b0 P1 w5 `' M2 w7 A% ]9 z        if(TX_n>0){
! e+ o& U+ V' H% k' ^3 x/ N' Y                pbuf+=64;6 w$ `3 V* _* _* v9 T$ K
                if(TX_n>64){
0 F# G6 H# S, @( [/ E                        a=64;
$ k4 }6 b4 u8 L4 b                        TX_n-=64;
8 _6 C: l7 y8 V. b; Z+ f0 x  P! C                        
8 t9 j( Y, B- o                }else{
- e" P+ e6 J& g$ z8 ~/ A                        a=TX_n;
) w% s8 l$ W8 O: A/ y. `7 b4 k8 u                        TX_n=0;4 r+ |* m5 C; _; j" R
                }
- p0 j- r" F4 F* z                + v/ ]' l8 q4 r  _/ a/ N% B
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);- V7 M; v$ K) }( B
        SetEPTxCount(ENDP2,a);
+ \. i, s( R: U/ J" A               
: ^5 E+ V' r$ Z& B1 s* h        SetEPTxValid(ENDP2);- {. Y# G# G% ?# N" o' y% p
        }else{8 }( m$ i' @6 @
                #if (SWO_STREAM != 0)  s# \) i7 V- ~) Q; C, _9 F
                SWO_TransferComplete();
, x% d2 x* m" t7 J4 `- B                #endif
# H* h0 Y# N# m' C        }
7 K+ o9 ]) C* J4 N& b}
! ?4 g+ ?8 A: c$ z  N( N( O4 u+ ?/ L; h9 f; a) i
/*******************************************************************************
! y$ F" Y  t: p3 w/ b* Function Name  : EP1_IN_Callback.; c& h9 |* t1 d& ~  z0 p# ?
* Description    : EP1 IN Callback Routine.! W+ [4 b( \) d6 i
* Input          : None.
8 `( U* ]' R/ B+ O* Output         : None.
3 P! }; I- S) j* Return         : None.
1 Q  M" x5 |/ Y( {& o6 P*******************************************************************************/) G( y: s' }' z7 k
void EP1_IN_Callback(void)
  _3 x/ {, L8 Y9 Q+ h+ i/ T5 t, G9 Q9 X{& c- r7 h& l  N/ N5 D
    if (USB_ResponseCountI != USB_ResponseCountO) {
; m8 t3 ^; m3 n      // Load data from response buffer to be sent back
8 R9 o$ y  N: Y                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);: h3 O4 v' k9 |, z1 |& Y
                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
% S& f! A, s1 X# V                        SetEPTxValid(ENDP1);                        
' A6 S4 D9 H- |# F# B8 k% w- ?      USB_ResponseIndexO++;0 A; ]5 T! J4 T' g
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
/ N' t; t3 `/ S. l( g        USB_ResponseIndexO = 0U;
5 s! j3 [8 R, C. F      }
2 \. V: ?3 X# D3 J: o      USB_ResponseCountO++;
( X  a1 r# T: i    } else {6 \  r- E+ |: n8 a" E
      USB_ResponseIdle = 1U;
; K, x0 g" ^& s    }  : R  {" j# w4 g6 u2 r7 V
}
# ~6 \' q$ P; H% h- X9 ~
4 S: O' Z/ Y' H( @* T// Called during USBD_Initialize to initialize the USB HID class instance.. f  s3 u$ ?& v: ?
void DAP_FIFO_Init(void)
, T- E5 O' n2 T% b- q% H7 t{
' R' p8 P. v7 f# ?    // Initialize variables
' l3 Q- w: a5 o, \2 a- \$ `! p    USB_RequestIndexI  = 0U;
) {4 C, x- @, {; D, k- _    USB_RequestIndexO  = 0U;
# \8 `1 n, B" D! I' U/ ?, a    USB_RequestCountI  = 0U;) b" M2 X% I% n8 I$ X9 s$ {$ Y
    USB_RequestCountO  = 0U;
1 ?7 ?6 k1 P1 T  r5 k    USB_ResponseIndexI = 0U;6 o5 I: t9 Q% O
    USB_ResponseIndexO = 0U;
: H, _1 |7 h; O8 B" p  G    USB_ResponseCountI = 0U;
) w" G/ U: K  e$ n% r  L3 n    USB_ResponseCountO = 0U;
0 ^* V) q; V# J; a. l& A* r    USB_ResponseIdle   = 1U;
, d( o3 n7 Q* d0 y# R8 C    USB_EventFlags     = 0U;9 w4 P* ?7 d. Y( }3 Y
}; D- e3 n% h3 K# [( r0 x
9 m+ Q6 p8 r& |- T! k+ {
uint8_t DAP_Thread (void) {
& S1 ]  S' a# E8 F$ [8 b9 Z  uint32_t flags;# D$ V2 x- Z1 E% X; k4 [
  uint32_t n;
8 Y3 b/ S# g( N9 M9 w/ I! y- \9 P
% t/ P8 B2 b. n4 H: ]  //for (;;) {- }) H8 H! G6 L3 u$ Q3 ~$ ~4 l
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
) o/ f7 S1 M/ e2 F                if((USB_EventFlags & 0x81) == 0)
+ e0 k$ u5 E/ s! e0 H9 q                {  Z3 H' X4 r4 b1 f4 R
                        return 0;
- b8 k6 Q6 Z) V                }
' o7 v4 l( c6 [, Q                USB_EventFlags &= (~0X81);( E( `- r( d# `2 b- _3 Y& f7 I) b
                ! n; \7 n" t8 Y4 m$ l9 |% l7 u% S
                                       
' q! R2 E& ?" B' ^+ L( n    // Process pending requests
  g) a# @' o; W  J' o7 \    while (USB_RequestCountI != USB_RequestCountO) {* O5 ^' N8 e' c( n  H" j
                //if (USB_RequestCountI != USB_RequestCountO) {0 R* v. T/ o3 C2 m) V" T' n
      // Handle Queue Commands
+ t8 E5 V0 j+ e0 a+ O      n = USB_RequestIndexO;: k3 {0 Q; E+ V# i  w% I  h
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {% u4 u/ M$ k+ r3 G
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
9 e5 r6 {' ^, S        USB_Request[n][0] = ID_DAP_ExecuteCommands;
. v0 }* ?1 k5 {6 v) X1 D  m        n++;
0 \- h: v8 C9 g* _5 _# u, Z        if (n == DAP_PACKET_COUNT) {0 {5 k- Z* j) A6 [3 N* {# b+ D; A' U
          n = 0U;3 {- y. p: [2 B8 g2 t5 F2 h& }
        }
; A  }- p3 k% h        if (n == USB_RequestIndexI) {# y% a# u  I2 o# {1 t  O  o
          flags = USB_EventFlags;' M5 \0 [  q# i; t, s
          if (flags & 0x80U) {5 V, O; _7 c: f( c1 L
            break;4 ]2 j0 f0 |' A6 z/ Z5 o7 H
          }
9 {3 j. n! e6 _7 d        }3 K! y" E& S, R& t8 i2 @+ }$ J0 B
      }
7 @8 s5 \" U0 |$ A# p( b! N( F# H8 b
: j6 g! n7 c: K/ H1 j      // Execute DAP Command (process request and prepare response)
  g- H$ m2 z9 A      USB_RespSize[USB_ResponseIndexI] =! j# W+ l1 R6 A0 ?1 s6 M
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
8 a1 ]" W  T; R& `, @3 c8 d+ u5 t, g0 V( _
      // Update Request Index and Count
& C& R8 j  I# a! W/ p" L/ m      USB_RequestIndexO++;
' T/ @. q3 }% T; E      if (USB_RequestIndexO == DAP_PACKET_COUNT) {' i9 A- I# l6 h( R% @8 v
        USB_RequestIndexO = 0U;7 U6 Y) `) B  r; ?, ]5 b- h/ @
      }- K3 q$ {. ]' z7 c6 \( Z
      USB_RequestCountO++;* R+ j+ M; }- o" f6 U- x( M% C
  A: r' }6 R& F/ w
      if (USB_RequestIdle) {
0 F1 l$ t; Z- R        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
7 R. r, N% A  ?. O. c( i1 \# S          USB_RequestIdle = 0U;
. W9 M0 I! w, n2 }- a9 p          SetEPRxStatus(ENDP1, EP_RX_VALID);9 }! `# m4 `& O) n
        }) p1 R' ]( X9 s. K+ N( z. ]
      }
. m4 f# Z" y- K
, ~& t. `8 ^& m0 d6 W      // Update Response Index and Count8 t6 \  F' m8 B/ ], X; L
      USB_ResponseIndexI++;
# K  M7 P8 k' X) r! j. x      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
$ _9 g; K" z0 C- n* s, }        USB_ResponseIndexI = 0U;! ?' e! w& ]+ I0 x
      }
* y& {0 L8 u  Z# [- n5 l      USB_ResponseCountI++;% X3 W8 D! ^1 v6 a
' Y8 t$ N2 p+ ~$ h% p/ |- m# p- {
      if (USB_ResponseIdle) {
5 {9 t# s2 y3 h8 Q4 s- A* j" O        if (USB_ResponseCountI != USB_ResponseCountO) {
; J( ]3 m5 U' O7 Q+ q3 y( a7 t: u          // Load data from response buffer to be sent back
* X2 K. C& E$ g0 e          n = USB_ResponseIndexO++;
, C% K8 W; p% u1 Q% y& {          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {% X/ o8 U* t0 m; h% _8 o3 S
            USB_ResponseIndexO = 0U;3 O8 `! n* p- a. @4 k. a/ e! {' m
          }
+ b+ }: k# r% d5 Y: j4 A3 o' v          USB_ResponseCountO++;; J: ~. M3 C* k- j: q$ G
          USB_ResponseIdle = 0U;
' [/ @& d6 B0 H          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
3 Z* b/ l' _. _2 j: }$ f* ~                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);8 ^4 W3 f7 e1 H0 X( s& {3 i1 R, p
                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
# ^6 l# w6 o% [                                        SetEPTxValid(ENDP1);
0 R" J* U3 g; e! k        }
* s5 m- X0 s. _# C  R      }
- ]: e$ a/ Y, ^3 h5 l3 i5 g; x    }. \% t' N9 s5 z9 m' _
        return 0;
% E% G2 f5 E1 e" n$ m}/ q% m. _$ f1 u, B' q5 E

5 {8 z- k( p; @* E$ A( G// SWO Data Queue Transfer
. S! ]$ M+ Z- U- |- h/ U# m$ I2 Q/ X//   buf:    pointer to buffer with data+ Y! G- p2 J. r) ?& D; w
//   num:    number of bytes to transfer
, z9 b  E8 I  g& ^! C/ Y! r/ e5 ^, Kvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
3 k$ a- Y9 Q6 v" J' R' \! j1 K  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
; w% u; ]4 K1 d) o        uint32_t a;
6 ~) u' f9 D# t$ H; U        . l2 D" `& M  v' U* J
        if(num>64)
7 a. W( {5 L3 J# N        {
5 h" |  S  [2 x& \3 p2 Q) l! ^                a=64;1 o* X6 L/ o) C& E- x! u5 }
                TX_n=num-64;; G" j/ u! a, i+ R  L( M, E7 H- j* R- f
                pbuf=buf;
: L$ V& r% g: u; n$ @. }9 i' O
" u4 h+ L6 U' \% C# b- n        }else {
  z, V& b8 X3 p0 d                a=num;
$ q2 B5 U. z- N1 m9 P3 \; R3 Y                TX_n=0;
. ^. j6 e! T7 B- b9 K$ f        }; V* }) w; l* `( y+ }
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
0 |& Y$ k) f: x        SetEPTxCount(ENDP2,a);( i+ Q! F4 F; [5 X4 b
        SetEPTxValid(ENDP2);
: }7 i* U% E$ t* V& @+ C" ]}
' l" S9 S6 z* I8 k; p6 N  v6 k6 T5 ^9 P7 j7 C6 Q
// SWO Data Abort Transfer
0 v) D% n' s9 ]3 F. d& rvoid SWO_AbortTransfer (void) {: g: {/ @. R- |- E  f& `. z
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
# N" x+ N( K4 O. n9 @+ [# q        //SetEPTxStatus(ENDP2, EP_TX_NAK);
! B. K% S" w, c; G5 j% f        SetEPTxStatus(ENDP2, EP_TX_DIS);& O8 L! v* n* z: P) {8 x- B
        SetEPTxCount(ENDP2,0);
1 i' r" f& V: U7 V% |9 @        //TX_n=0;" m3 U* b# n( z7 @
}  m& a, [% m$ ^9 u- r
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
# f% y2 l! h: U* ~  K6 d) \* b0 }" q6 m7 {% l% L- [1 }
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处, e9 b9 m. W( T4 I" l( w
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了& f' R# S7 S! m
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {: e7 C1 r3 x, J$ W* G5 U
  return (DWT->CYCCNT);
6 A7 o) L) m/ m6 B9 n5 i}0 j0 m; N3 h- b+ v1 `) {1 O# _

8 B7 h4 S. c: X4 l! O! lvoid DWT_Init(void)
  ?- Z" h: {2 }' M2 \{
, L3 R! Y# ^. M3 I$ d/ |3 I    /* 使能DWT外设 */
7 S4 x- n$ {) b+ N( c  g    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
8 E* b- [$ `! I  x6 j- H8 T' I+ o: ]/ V: J$ g) U4 u3 b; @
    /* DWT CYCCNT寄存器计数清0 */
) j3 t) w& R* ?  K; @    DWT->CYCCNT = (uint32_t)0u;
: _1 u( q# i$ |! v  [5 c* K" w/ `& j6 y" s
    /* 使能Cortex-M DWT CYCCNT寄存器 */
6 L; O! r4 O" @    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
& c  u4 E& M: x! Q8 ?4 R4 M& H" g4 N2 O* |}
5 B% C  m; o- I8 u        % a# Z$ O' l( Y! f

5 H; R4 s0 }8 a然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
- F( B% S$ D1 e9 _6 D6 c) w! |# b( z" |; p' B% h3 X  R
然后改为使用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不香么?
' t( Q  B( T# G$ F) O# t声明这个变量static volatile uint32_t SWO_EventFlags=0;
) Y6 q% v* J" T在SWO里每一处调用osThreadFlagsSet的地方都改为如:
5 ]$ ~2 B9 n% C( o/ M1 Q//osThreadFlagsSet(SWO_ThreadId, 1U);/ p) A, H$ p8 u5 n& f4 T( x
SWO_EventFlags = 1U;
. u( }, k, n" b# D: N: ~2 ~& |7 @
; x/ ?, e2 f8 U0 |; o4 C
// SWO Thread! {* Y$ l+ x" ?3 A: h3 L
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {! ^/ e$ }0 L, {/ t! {' n) m
  //uint32_t timeout;
9 P* {) G  p7 `9 f6 v$ b  uint32_t flags;
/ q6 F: z0 v4 {! \  uint32_t count;
# O7 Q* O* Y. u* e9 ?  uint32_t index;
5 ~" R5 t4 i8 o  uint32_t i, n;
( X: [  C8 e  \/ Y; T8 g% u+ F  //(void)   argument;+ i( s4 q% \; |1 z+ M0 H) k4 v9 \' `
' o* \: F  r+ R; [* a* V$ ^5 U  K# \
  //timeout = osWaitForever;
6 J5 J' c, g& _2 G/ G( `/ J9 A% E3 q% b  x0 Q& n
  //for (;;) {, _5 b: ?; [3 V6 l' z- w* O  k
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);$ S5 o6 p1 {) {- B6 M) X; F
                if((SWO_EventFlags & 0x01)==0)return 0;+ i8 X0 m4 ^6 W3 C7 Q  r
         ; |# j9 L! }( y! u/ w
                flags = SWO_EventFlags;
8 C. a* k: q* C" B( h                SWO_EventFlags = 0U;
9 j! i+ W; x; G/ Y- o& {& Z" \4 ?    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
6 l; Z- k7 M  C* o$ [) W& V" J      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
. a. F; I7 s& o% M                        ;. M* G+ `4 ?: s/ l, e
    } else {; h) e5 O2 n2 ?& J! a. P
      //timeout = osWaitForever;+ K3 G0 n7 G3 \' i. B  c
      flags   = osFlagsErrorTimeout;
2 U6 Y" ~1 r% J2 d3 p1 E    }8 C: V5 C9 q8 t  G6 [5 h
    if (TransferBusy == 0U) {; x: R0 }5 Y- a8 S* Y* m3 |1 K
      count = GetTraceCount();% V1 G# h* v* F. D$ o4 i9 T
      if (count != 0U) {
' i' A; a7 i: I  P. y        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
  d5 Z  V& B$ _6 Y8 ~1 ^        n = SWO_BUFFER_SIZE - index;) S/ V$ `1 y1 D9 M
        if (count > n) {$ E7 L! G( S5 f5 ~- B" }
          count = n;
# q% ~* ?, Z1 p5 y4 A                                        3 o9 D; t* t; \/ q) m/ I
        }: |+ ^6 U* p2 D, R- f2 M, D
                                if(count>USB_BLOCK_SIZE)# k) H% X2 E/ w9 i$ [
                                        count=USB_BLOCK_SIZE;5 [$ V$ R  P! y; T- y7 ~
        if (flags != osFlagsErrorTimeout) {
5 B. b1 I5 g- g8 T6 j# ]          i = index & (USB_BLOCK_SIZE - 1U);
5 z) b) D- Q+ w! k* v0 \          if (i == 0U) {2 {8 b" v9 i7 C9 Z
            count &= ~(USB_BLOCK_SIZE - 1U);
% Z' G5 t' J, a& C7 F( t" M  S          } else {1 }0 u; o) ^3 p
            n = USB_BLOCK_SIZE - i;
" A6 C# {3 ?) p. l            if (count >= n) {5 G" P/ E% f  D
              count = n;% }  N6 W: s8 @0 |* O  R/ |2 x
            } else {2 \) q. Z6 R# \/ D5 a
              count = 0U;6 w: B9 u0 m' W
            }' Q, u1 O, N& _/ I( P
          }
: M5 {! N5 s5 H        }  \2 w# C6 T: W1 i9 _. T; q7 S
        if (count != 0U) {
' F+ K/ h/ K% g          TransferSize = count;
6 ?# H+ |( y2 m* x0 c: B1 b          TransferBusy = 1U;
' B& E9 ]8 n- U. c          SWO_QueueTransfer(&TraceBuf[index], count);  f. _: @- l. l. X7 S+ K
        }8 ?0 b- G5 [$ e- J2 o% C
      }
& _. E6 F! V. ^; u7 H$ x    }, S1 V. }! p2 W$ d* t
  //}0 a( u4 l* [$ I0 p: r! Q* y
                return 0;7 t7 s) \. D* u1 x- p& Q3 \( B5 ^
}8 B. N# H6 \! y
利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
% b  B4 F  {& l2 [#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
4 c% J( W2 P; _3 f5 H3 e4 x. J8 sstatic volatile uint32_t SWO_EventFlags=0;; J, E' W& H' r& Z% |
static volatile uint32_t timeout=osWaitForever;
0 l- ]6 S9 i% V. u, x* Z& t5 v4 Nstatic volatile uint32_t timeWait;
, |" u# l. t; t2 @, l函数改为这样
" @! B9 `, |/ W/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {9 P8 N4 e2 n& N& J# R
  //uint32_t timeout;
# a4 ?7 D! o& {  uint32_t flags;* n2 P5 ]) b9 h$ v" e+ i' y7 q
  uint32_t count;
7 G  _% b1 a3 O: F4 r' o4 _! n  uint32_t index;
3 M2 R# @5 O/ x4 H; F) m$ k  uint32_t i, n;
, z3 l1 k* a$ ?* H+ Z/ j  //(void)   argument;3 R9 {8 k1 I% E; C+ L. M
: X) E+ m3 C) M6 D5 Y$ y) q
  //timeout = osWaitForever;
+ \% k5 b- d9 D( C1 R2 M
( i. I/ y$ j+ Z8 b: J$ S! M1 i6 _& K  //for (;;) {
  q( }, _" e9 \    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);+ x1 }2 A7 a" }4 {- E4 j( }
                if((SWO_EventFlags & 0x01)==0), O; }9 k; O4 j$ W5 f) Y
                {
2 y; c/ v. p- @                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了, G+ s# ?* [  S! y
                        return 0;+ W) J9 w" g9 k7 D
                        4 a; Q( f9 n& y5 s: l/ P
                }
: F7 O5 x, W  E( i" _: u         
, Z& U* `6 ~: ~. v6 o9 l4 @                flags = SWO_EventFlags;2 i* X2 G# Y8 P, c/ l/ z
                SWO_EventFlags = 0U; : N" S5 M; m/ b& _7 F" o
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
; ?3 j3 N; D$ o' C; o- C      timeout = SWO_STREAM_TIMEOUT;! e: u4 H3 R2 D$ m" V8 p
      timeWait=DWT->CYCCNT;
) j- p  |  i1 H9 e; w/ q; B  h    } else {
( n8 o( w2 m0 B7 r7 R+ k      timeout = osWaitForever;
5 o7 h; w. W% [      flags   = osFlagsErrorTimeout;; k5 K, X9 h5 T4 H
    }2 E3 N6 c' e% ~- v
    if (TransferBusy == 0U) {
0 i3 T7 Y. Y: _4 g: ?( w# i' Q3 m, W      count = GetTraceCount();1 A. H8 d4 L7 b- {
      if (count != 0U) {
& L" U) y7 w) S5 I( [        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);7 x' v9 A' g; C$ g; e% C
        n = SWO_BUFFER_SIZE - index;4 Z3 v! t' S7 H1 f# ]0 |
        if (count > n) {
* F' u6 a1 V  \% ~- T! D          count = n;
2 H' ^4 B0 O2 Y                                       
2 t& C9 ]; B- G        }
" n' Z6 T; z6 B6 G# S7 h- m, `                                if(count>USB_BLOCK_SIZE)1 r& i3 s. G" e/ U8 b% U. `
                                        count=USB_BLOCK_SIZE;: H5 A+ l9 i  o" j2 m
        if (flags != osFlagsErrorTimeout) {' |* C8 z% o! d! H, q) E" P3 u
          i = index & (USB_BLOCK_SIZE - 1U);
8 @! ]' P0 g$ P! j* y7 y          if (i == 0U) {
2 n6 X& C9 y% u) {  }: C8 R. |            count &= ~(USB_BLOCK_SIZE - 1U);
3 {6 u) Y1 t: R) P          } else {" o8 ]4 }* z3 a" |" r# W: J
            n = USB_BLOCK_SIZE - i;
" {. h$ N3 K  F7 n* P5 o( f            if (count >= n) {+ \2 Q! J2 M! ?: J# ~
              count = n;; I  d4 m4 N7 n/ x- ]9 K
            } else {
+ l8 [. ~$ a% U. x7 \  K+ F# Z              count = 0U;9 g7 J+ q) A4 [8 C
            }
& D. c" O6 W: i/ A. G# Z          }. J. A* m& o* w- y( Y
        }
7 J5 I( a- A5 q* T        if (count != 0U) {
1 F  ]9 ~% v# j% m5 p          TransferSize = count;5 D  L% o: m0 W, n$ }$ I
          TransferBusy = 1U;; H1 H1 t& Q9 F
          SWO_QueueTransfer(&TraceBuf[index], count);
5 k+ c/ }* ]# q. k& z6 a        }: @. c# n( T2 B1 j3 p' M
      }, w: G& c* _" T+ D1 X* o
    }! c( T) l% E2 ]
  //}& @- l% q5 Y& _- C" v& E
                return 0;6 |; ?2 U+ M( B0 A" t; a) @
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了& M& P. ~1 q5 ]3 u

7 |5 h  }2 Q3 `: {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,少了这个等待时间,能增加端点的传输速率
8 b5 W! i9 Y3 U* Y' W1 @. V9 ~7 \6 S! F$ \

" e6 k7 e  ~) G: K1 Hint main(void)2 \. }, N2 I: l' K4 [
{
3 @0 A7 n  k; }6 M3 r$ l; ^  DWT_Init();; U' z' z$ ?" U7 R9 ]
        DAP_Setup();
  A+ K2 d( r$ Q, b: s+ y  USB_Interrupts_Config();6 i& r7 O  G' n
  Set_USBClock();
2 y, T/ A, l( F* {8 s5 g& r  USB_Init();
+ p) @+ k, U& ~) {$ V+ F3 L1 v        //TIM3_Init(35999,0);. h1 Z0 T9 }; W& v3 X! z
        //TIM_Cmd(TIM3,ENABLE);+ I* Q% R0 _4 F5 f
        8 s* p/ K. P, H0 ^2 D1 K% X$ G% W3 x
        " J& i6 c/ f8 c0 d0 ?; Q8 X" s
  while (1)
  q5 Q& G" `  @  t2 H  {6 {$ H/ v$ C; d& s/ ^
                DAP_Thread();
& P: }( J& E% B$ \! p                #if (SWO_STREAM != 0)
+ q* f0 E; p* ^) a$ Q* [) J                SWO_Thread();; O5 N, C1 |5 P6 n9 W/ j) B
                #endif
3 X# u% \% H) w+ r" d3 U; t  }
  O$ ^) m6 f* M' K% W+ O5 P}
2 O8 p$ A* }3 o9 ~$ V' P' {0 H& A7 Q: \; k- |4 K; \; J
对于DAP_config.h的IO配置我是这样弄的0 K% M4 ^, j) c) e% d  t: x
///@}1 [- v2 X4 }$ e8 X
// Debug Port I/O Pins3 H) K, T  k$ ^5 z) n
) s8 Z3 d1 N3 L4 K. N. k
// SWCLK/TCK Pin                GPIOA[6]" ?2 A! L0 n7 R
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
" W3 c! _! f; r: |4 [#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
6 ?2 {; G& V" n# |0 X8 n% `( h& o9 R1 X
// SWDIO/TMS Pin                GPIOA[7], e4 H, Z, a5 s" t1 [
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
  M' k: U  d% S, N#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C* D" `- }- P) W& ?

2 W$ M6 M3 u; Q. L// SWDIO Output Enable Pin      GPIOA[7]7 B9 V6 c0 D5 a$ j. s
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
& s6 y* }0 t/ E: B                                                                                                                                *(uint32_t*)0x42210070 = 1; \: [$ l2 G3 O7 ?8 Z* u' t2 M! r
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
6 f( I( e! W4 x2 ?" E                                                                                                                                *(uint32_t*)0x42210078 = 0; \* C* ~6 v4 Z" ?1 p0 p$ ]/ y
                                                                                                                                *(uint32_t*)0x4221007C = 0;}
* v& P# t2 l$ d/ Z4 s5 C1 T/ \1 s% w  I4 b, P: i7 p
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \6 ^, l1 @9 I' V
                                                                                                                                *(uint32_t*)0x42210070 = 0; \
6 \0 x: A" R- |. r7 A  g+ P0 c! K                                                                                                                                *(uint32_t*)0x42210074 = 0; \
; Q( ~- e% U4 c, I% Y                                                                                                                                *(uint32_t*)0x42210078 = 0; \' M$ n7 K1 {: P# A
                                                                                                                                *(uint32_t*)0x4221007C = 1; }: ]& N* @: U- F" E2 L6 y6 C% M
3 z4 v  m+ a) E9 k! j3 O% d
// TDI Pin                      GPIOA[8]
& t0 T  u! o3 W# t0 }. G#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0/ v4 V. Y. M& M
#define TDI_IN                                     *(volatile uint32_t*)0x42210120
. }: ~2 R) @; t5 Z1 A# {; N1 Z
7 H. d1 R$ o. A+ S/ w// TDO Pin                      GPIOA[10]
! X5 ?; A, ]4 m" c9 q% w( d& J; n) O# [4 H#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
( y2 C7 w; i$ N#define TDO_IN                                     *(volatile uint32_t*)0x42210128
, c% }. }! m2 f' x; B( b" G2 ]$ X- X  `0 K; ?4 E
// nTRST Pin                    GPIOB[3]; r; ~$ M' D0 y0 P! ~' k% n
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
6 C- K3 t; K6 Q  W/ l6 c9 _! k6 F#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C* N; |) w3 h1 W4 u  j7 T4 P

, i& s: b, c$ L2 C1 L* S3 I# m8 c// nRESET Pin                   GPIOB[4]
2 A' o6 e4 R, e+ d#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190, n; J  `+ H- u. l
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
9 U. l+ [; |8 u2 f* t2 l3 f5 m" t. V0 |0 u2 b) V
// nRESET Output Enable Pin     GPIOB[4]& Z* v: T/ s" \4 d* |( M# \" |( [
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
5 m& q* B+ Q& @: j4 k3 A' p5 h2 _. v                                                                                                                                *(uint32_t*)0x42218040 = 1; \
  ?- Z0 X" ]6 w                                                                                                                                *(uint32_t*)0x42218044 = 1; \
! ?2 y5 [2 \9 t; x+ R                                                                                                                                *(uint32_t*)0x42218048 = 0; \. J* D( @+ \7 Q4 ?/ I3 y$ X
                                                                                                                                *(uint32_t*)0x4221804C = 0; } 5 y. y% G* I" z/ d6 l
+ F3 U# g7 e" W- A( I$ K
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
" E/ r8 W5 _" y  B                                                                                                                                *(uint32_t*)0x42218040 = 0; \2 S/ }/ O6 }) z# s: }  {
                                                                                                                                *(uint32_t*)0x42218044 = 0; \* _+ N3 q9 t6 `* D6 U
                                                                                                                                *(uint32_t*)0x42218048 = 0;\1 @/ g4 \, T3 p& I' r3 X
                                                                                                                                *(uint32_t*)0x4221804C = 1; }6 u0 C/ E) ]7 b5 R
3 A; b$ I: M. C# Y$ ]( a9 N0 Y/ r
' M$ A! [, h) P) i
// Debug Unit LEDs
9 |$ k1 b& _" Q7 N+ E% q- j; X6 g+ B! `5 z, b) u
// Connected LED                GPIOC[13]
2 u: G: k$ [; V- b! G6 s7 R3 I! `#define LED_OUT                                                      *(volatile uint32_t*)0x422201B43 |# P; Y. ~0 R$ n, V% x
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
/ I# O/ n& O# Q+ D1 w7 M  @% S
2 f3 Z& J; {: {/ Z9 b% l2 X#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \" h) k; ]& [5 P1 _/ E" |6 p5 _9 f% Q
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \. S) H# v3 L8 ]# H8 \$ s/ Y0 O) g
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \% F" L6 w( {  _$ V0 _% w2 E
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \+ }! N  Q' ~" R) A) c/ O8 S
                                                                                                                                *(uint32_t*)0x422200DC = 1; }
9 h5 b/ d- d$ O" D( y  B// Target Running LED           Not available
1 K/ j( Y8 e, V% H% n8 u4 `' U. x) n. I4 Y2 S
// SWCLK/TCK I/O pin -------------------------------------5 N1 M- @* X3 A% r( S. ~

6 j# m) ~1 z; j5 M. u" j/** SWCLK/TCK I/O pin: Get Input.( |6 K; r/ ?+ b8 ]
\return Current status of the SWCLK/TCK DAP hardware I/O pin., Z8 L. Z; O: O
*/
" s0 v3 ~0 n8 \1 E__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {" X4 E% G! e0 ~% a2 U
  return (SWCLK_TCK_IN);
8 P9 j: l: \* }}/ a4 W% N- r! B: [$ B

) L1 E6 ]0 W, S+ Z4 _/** SWCLK/TCK I/O pin: Set Output to High.& p+ u, m0 |% v6 L+ \/ p0 t
Set the SWCLK/TCK DAP hardware I/O pin to high level.
, ?0 d  r- w/ q*/
8 s4 |* W9 o4 L  o! s__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {" ]2 Y1 D, _1 x
  SWCLK_TCK_OUT = 1;: D$ u3 e) \3 l0 {3 \% U" R3 k
}
6 F( |& P% h% I/ ^, c" T  b9 B* s* {
/** SWCLK/TCK I/O pin: Set Output to Low.  Q6 H" A7 V4 e: t
Set the SWCLK/TCK DAP hardware I/O pin to low level.
; |1 @1 V% L! D*/
3 p! K8 t* O# }__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
* T6 O( |0 |* ~& c5 @0 n  SWCLK_TCK_OUT = 0;* k& v! H8 _# Z; s. A9 j7 i2 O
}4 f8 G+ f0 U/ M2 p! }) b
+ P3 |. q3 o9 A$ ?/ Y' R; e3 a
+ d* ]) H% V$ N6 ]' q% F' H
// SWDIO/TMS Pin I/O --------------------------------------
& h3 [0 }- E' H: Y) h7 j8 U( m0 i4 S8 y* c# }9 S
/** SWDIO/TMS I/O pin: Get Input.
3 A/ \  |0 R" k) j\return Current status of the SWDIO/TMS DAP hardware I/O pin.
3 s5 Q0 {; \; R5 U/ r( k*/
3 n" T; v7 X* x2 {: A5 ^* [__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
# ]: i9 [* Z( [  return (SWDIO_TMS_IN);% a5 j0 p5 c5 U6 f* h9 m' Q
}% {& o* R- R. c' @& R
! S- M4 ^! Z0 x# o8 W
/** SWDIO/TMS I/O pin: Set Output to High.
) v* f8 g1 i# Z6 x" }4 r: [# WSet the SWDIO/TMS DAP hardware I/O pin to high level.
- j' E/ ?* W  L- [, L% H*/4 E0 V# u/ @4 k9 I4 E# `6 q& v4 j# N
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {! g6 J' I$ T7 X# u! J" q' C
  SWDIO_TMS_OUT = 1;
; v, t9 x' S8 ~4 V}
! S3 l, w, s, f) K7 u: l8 i  ~/ q
+ m5 O9 E' l7 }/ E0 F# o+ X. J/** SWDIO/TMS I/O pin: Set Output to Low.1 k  I) C6 A7 ?) N; z
Set the SWDIO/TMS DAP hardware I/O pin to low level.( z+ l/ U& E1 T' ~1 H& N8 L% U
*/5 T5 F" t0 K  L3 O
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {5 S1 g( h( d5 l
  SWDIO_TMS_OUT = 0;" p: G! A" ]' G& f" _; f
}" p0 C$ B8 }( p2 x; j
& z  [7 G0 w  T: e% |0 ~
/** SWDIO I/O pin: Get Input (used in SWD mode only).
, q' `0 u' j- b( e\return Current status of the SWDIO DAP hardware I/O pin.
; H* [4 l. \0 \9 v* [" L' |*/
8 l8 y& U) P" f__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
, G5 i, ]6 ^+ j  return (SWDIO_TMS_IN);
4 b4 ~/ `3 [& C; O* k9 P  R9 _, r, f}
+ R) T. r3 K% `6 m' f# p7 N9 }7 y+ e+ x, M; _4 z+ l( }, `7 ]
/** SWDIO I/O pin: Set Output (used in SWD mode only).5 g* W5 x- |, q$ S. W0 `) j
\param bit Output value for the SWDIO DAP hardware I/O pin.
6 p6 w; S4 W* a$ g$ x*/  g* t6 u' R( o: _  G; e! Y6 `
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
% ~2 ^0 B. g7 b; f+ H  SWDIO_TMS_OUT = bit;
' \9 L% _2 x$ Q# a" d% w# I' D6 Q}( _. g6 k" M& Z$ b' y3 y) Q

9 h4 g: [# i! ~$ Z* o. t/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).2 M- J: T8 |: p5 t$ y- E
Configure the SWDIO DAP hardware I/O pin to output mode. This function is/ y  m" c* K% S- Z
called prior \ref PIN_SWDIO_OUT function calls.0 @# |( l% F' |6 V' }/ ?/ i
*/
2 _2 T+ F: Z$ U! K$ Z__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {: ~7 X2 m5 ^2 E, @9 ^
  SWDIO_Output();' @& m6 K9 s1 w, o
}
8 C3 ~, j+ y4 u8 }
( X* Z. b  G4 q/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
8 d0 u& L- F0 S" {. M2 OConfigure the SWDIO DAP hardware I/O pin to input mode. This function is
! `0 m: x3 X( q' T( Fcalled prior \ref PIN_SWDIO_IN function calls.& F4 ~" J0 Y& I
*/, F) G) c0 A, i) q& D
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {; b% w# E4 u2 \3 n1 N: V" j
  SWDIO_Input();
( d& k/ i( `0 M" `# C4 b5 M- Y}
0 ^' q0 @  u" }7 A3 h" l5 ^! I
  q6 B' z+ O% Q( {0 X楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
- L9 e/ u) e5 A( m5 [3 g即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
( E# `' S: V! v! y
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

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