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

【源代码】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 r+ D: P3 \* b% ^* W4 _
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
2 ?  t# y, o+ ]+ T( ?7 i除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
5 X- I- q* m: }: S' h( N
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
; }7 y! Z* A' I. M
  c. u2 C* U$ b; }软件复位是另外一种情况,需要向目标IC发送复位“密码”,Cortex的IC有这样的密码。 这就不需要连接nRESET线了。
ricklou 回答时间:2021-1-27 23:00:25
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号
radio2radio 回答时间:2021-1-28 18:01:27
ricklou 发表于 2021-1-27 23:001 G3 @/ n) C/ V) q  C2 x$ I) t
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

6 i9 |! x$ O: ]( ]% ~( wnRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。' y  C. {/ m$ C4 m# M8 r/ R5 d
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。8 |' J2 Z6 y3 p$ h$ a& T/ z

$ X/ i& E! o- R4 {3 A你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 6 ]7 k& @& i7 s) i6 B% ~7 D4 G
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
* D: w8 T$ H5 w% C( M2 V
  R3 i, H0 _0 n( J6 r# A
# O) J9 L9 c- _* K# J7 m# M
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?  l- Z8 K" ~. A: }+ ]
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
( }" J7 V- B8 R5 ~7 c, 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系统,轮询执行/ s" \* [- m  Z% V7 v8 O% ^
/**
6 m& V" Q- J  m* g  ******************************************************************************: ^' H. E8 O  H
  * @file    usb_endp.c
- v9 r3 e1 h! n6 r  * @author  MCD Application Team
5 \; b7 O6 F) K  k  * @version V4.1.0, \" [) `! H1 }5 _# X! {. m1 l
  * @date    26-May-2017. F/ @7 ?4 e# t, h
  * @brief   Endpoint routines
* E$ \; v& `5 {0 ?' L  ******************************************************************************
: h' y* @% z1 t, Q  [$ ~6 W  * @attention
, ]. ^+ L/ X' u+ C4 O  *
& z8 P$ Q4 G3 ~: H  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>6 B* j& Q# A# J1 |$ s$ ]8 m) d
  *
9 r0 y6 J- T2 Y; ^  * Redistribution and use in source and binary forms, with or without modification,
" L5 R# Q+ R0 P3 r; Q  @  W  * are permitted provided that the following conditions are met:6 Q; G( `! f# ?1 q4 A' F
  *   1. Redistributions of source code must retain the above copyright notice,$ \4 B$ Y7 P; [
  *      this list of conditions and the following disclaimer.
/ W) F; u( J; y7 E, p  *   2. Redistributions in binary form must reproduce the above copyright notice,/ W$ j: t6 K8 W# n( u# r
  *      this list of conditions and the following disclaimer in the documentation
: ~/ i- ?9 T; [3 R4 O  *      and/or other materials provided with the distribution.3 n2 X- Z, j" m6 a
  *   3. Neither the name of STMicroelectronics nor the names of its contributors7 |* S  I+ W1 u$ l3 S& e
  *      may be used to endorse or promote products derived from this software
' S- {* V% ]2 [$ n3 X# s; d  *      without specific prior written permission.% O# m9 d$ K  E
  *: B* u3 H8 D, X* ~
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"$ }% m0 V: P+ ?# r# L; Y7 W" Y
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
, N3 W7 u( ^" h  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE( _) [4 h  J6 U. b/ w8 v
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* N( N( x* L) j+ h2 n5 i/ m0 |  U  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  p7 ?, P* d1 v+ S7 C$ u  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
( l" C- r- n; M5 ]' G  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1 x) Y- b! b/ w; @% f  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7 n2 ~0 M' Q. V% t: x  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE" Z9 u7 o" c: z/ T
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.* U4 s/ A6 ~7 N
  *
% n$ Q1 y" ~' r/ R, P) `4 N2 z  ******************************************************************************
5 h+ x( P$ g2 K2 F  */
# i) y: N: ]" V. o# j/ p1 l
$ M' ^$ ^; j" Y9 ?3 u! P- Z! g* p$ R. S4 ^
/* Includes ------------------------------------------------------------------*/# s( j7 x5 [0 H' T2 Y3 y9 v2 i
#include "hw_config.h"
( {; z8 l& V( b8 d# C2 S#include "usb_lib.h"; O* F* D3 `0 n: n) W; Z0 a
#include "usb_istr.h"
" ]: ^% [3 t) i9 O#include "stepper.h"
  p) k* f* O: e3 y6 ]#include "string.h"# h; W, K" f1 b8 I/ k' s. ]

* j0 O. o7 [; R#include "DAP_config.h"
' V" m5 ^4 V0 j0 c( W#include "DAP.h"' B% Q8 v5 b; a
1 E- p4 b* a9 j6 O4 z+ t6 E

9 Y$ J" \- A9 V. m+ |! A9 H  P3 n/* Private typedef -----------------------------------------------------------*/1 P4 K- u5 p. H' W6 |
/* Private define ------------------------------------------------------------*/$ x* y  C( z' J, N9 y6 O; d
/* Private macro -------------------------------------------------------------*/1 Y: I. |# t, c/ N- s" C
/* Private variables ---------------------------------------------------------*/
: p( e& w0 \' r  {% V1 ?7 Nstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In
" z/ g/ p$ r, [! K: o! P0 _static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
7 ]  p! V( r  ^5 u4 f) hstatic volatile uint16_t USB_RequestCountI;     // Request  Count In
! @! T, E; R% S# ]; z& `static volatile uint16_t USB_RequestCountO;     // Request  Count Out/ ?; i/ r/ c7 y2 ~. l) @  J
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag) ?% D! l/ T  M6 f6 j
1 V) y5 u6 i9 J9 K) V' {) J0 p" i* s  c
static volatile uint16_t USB_ResponseIndexI;    // Response Index In8 M2 E( [* o6 \( J
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out. {( Y0 {$ J; P, M
static volatile uint16_t USB_ResponseCountI;    // Response Count In! `* d$ S" H( o; ?$ W
static volatile uint16_t USB_ResponseCountO;    // Response Count Out' Z. w7 Q- k8 W8 ]' Z9 [- V
static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
( ^! X- C  l, C5 t+ r: D' v* gstatic volatile uint32_t USB_EventFlags;. ?& f+ e. s! s7 p/ f

) H) a: G& q, u  h7 a( `- Vstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer! y1 @1 _6 q1 i/ }5 a
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
1 K" v8 {1 e+ ~static uint16_t USB_RespSize[DAP_PACKET_COUNT];4 G; r! b3 C* R1 C, a, k0 e
9 M. P' Z+ u6 B7 s8 H! U
/* Private function prototypes -----------------------------------------------*/
# u2 N5 Y) h& M. [/* Private functions ---------------------------------------------------------*/4 V" c' ~5 V1 r
/*******************************************************************************
3 ]( J  a: K) e* Function Name  : EP1_OUT_Callback.
/ x8 G+ I0 ]: o6 I/ @+ R4 [* Description    : EP1 OUT Callback Routine.* H: q  B# g9 ^3 T5 l; m* N* Y$ t
* Input          : None.
* F6 j3 l$ D& m- G* Output         : None.
( i: r2 f! M& b$ M- o% r& N* Return         : None.
! l" ]/ y) K  L1 E1 f*******************************************************************************// q( n' {6 O8 {; c5 k
void EP1_OUT_Callback(void)
& u. r" u( W9 @{+ a( N9 I  U: f# o
        uint16_t n;
8 I  M8 y# d3 C5 O
5 D6 T& k* h" }" d3 f3 G" G        n = GetEPRxCount(ENDP1);
. Y$ {8 p8 [1 q4 ?/ k        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);& C/ W# d% E$ Q
        if(n !=0){# N+ b' k2 F( u: S( c* f
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
/ x+ U7 k5 x, G' I1 U0 k  {, _                        DAP_TransferAbort = 1U;; z2 z4 U$ A8 }, ]' \2 @$ a
                } else {
; A* a" z3 J5 f* ^9 B                        USB_RequestIndexI++;
9 g8 J4 o- }- n  P* u      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
: X0 _! v6 m& L. n& q                                USB_RequestIndexI = 0U;) o$ l& {4 Z/ h- Z% e
      }
- P8 s! j9 \6 M0 q( D) _' V8 `      USB_RequestCountI++;3 d, @1 n( j% o/ B9 x
        USB_EventFlags = 0x01;
( `- a" p, o( j# i    }1 l1 B6 Y9 q7 I  c& i. h" |- M
        }        
+ l: B8 }3 I) Z' H1 e7 F        // Start reception of next request packet
  Y# {9 ?1 M* I' |        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
3 @2 H) d3 ~, J, M                SetEPRxStatus(ENDP1, EP_RX_VALID);% A1 |6 p# s2 S. {( @- f% z" Z
        } else {$ e. P2 \+ k1 W6 l
                USB_RequestIdle = 1U;( v. ^+ C) k  P# M. L
        }                        
9 C: {7 M( O4 Z, _3 |7 D! }}
$ E( L  _. T$ H
, [( D. L$ a7 A9 \$ B: H9 {/*******************************************************************************
, Y+ N* m0 G' D# M  q4 \! r* Function Name  : EP2_OUT_Callback.
0 N# I" Y; [5 c* Description    : EP2 OUT Callback Routine.4 o" q( p# h( P2 T; C" h& |
* Input          : None.7 V5 r. j4 \- b, l9 y$ s9 h
* Output         : None.
) f# D8 w( v) B* Return         : None.
3 N4 d/ f$ x; _. E2 Y- `*******************************************************************************// ?- D" c8 W6 e/ W2 L- G9 ]
static volatile uint32_t TX_n;; V/ z% Q( b6 C: E# w
static uint8_t *pbuf;/ E- E# E- O# D0 `$ C
void EP2_IN_Callback(void)
. F% u- q- r& F( E# ^; v, G{3 P- L7 ]: ]. f$ l1 m
        uint32_t a;
* E1 U& c0 e/ ?( {" U        if(TX_n>0){
1 A% [# c! n/ q! {9 n1 P# S7 i                pbuf+=64;, R/ h7 i4 }: T, X) h4 o+ X1 O
                if(TX_n>64){
6 |+ u, C0 u. [% y& z                        a=64;0 T6 v% b' H2 f1 H) r, d  l2 \
                        TX_n-=64;
6 b. I: `0 Y' f0 C. h' F                        6 W# O5 o( i+ o, u. g# f3 w% A
                }else{1 A8 B( {3 |0 E! _* Y/ l* I& z
                        a=TX_n;
  R6 K- u/ [& h8 l3 C7 I& C                        TX_n=0;
/ \  A9 `" h+ `( O                }
5 q7 g+ i  H0 p7 Y! ~' N# C                2 t. a+ l$ \' u2 `
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);4 y1 ^. ~: y! |7 O
        SetEPTxCount(ENDP2,a);* x' H; w. n2 |( r( k
                ' P' s2 Y+ u3 i7 W% A  Y8 S7 b
        SetEPTxValid(ENDP2);  n3 X: I3 C1 t6 O. H) C) b6 A5 W
        }else{
7 F1 o- D: P( y4 J3 I2 J: J                #if (SWO_STREAM != 0): v+ t7 E' q+ A. k; P- f' ?6 {
                SWO_TransferComplete();
& b5 _1 r+ M: Y+ z3 p                #endif
  H# J9 T6 i) S        }
3 q! l" g7 e, q3 G" ]' N0 b}
8 e# c# D; ^& Z  C  R7 M, _  h8 ^7 F( V# K
/*******************************************************************************3 p) \$ G3 E4 R  I, \, X6 E
* Function Name  : EP1_IN_Callback.- }) z$ V; {4 `, o
* Description    : EP1 IN Callback Routine.
: e0 D8 V5 j. a* S$ V5 u$ q( ?* Input          : None.
2 H* R( w0 b$ T) R. X- x! T* Output         : None.
/ k+ t& D( J, }& r. D: |8 K* Return         : None.
; e9 B( h: @* `*******************************************************************************/
' y, H6 m* o; ^, a. g. n; @void EP1_IN_Callback(void)
* X1 Q5 x6 H/ i% ~) J9 q{3 `) H5 p) s8 A
    if (USB_ResponseCountI != USB_ResponseCountO) {3 c2 \, {4 v5 P5 }, @1 K% N8 X+ U
      // Load data from response buffer to be sent back8 a& p" g( H+ E
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
$ n& T$ }+ ~" G9 a! ^2 u/ y: `                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
; l! E6 U* k) }+ E. i, r5 I8 A( @& S                        SetEPTxValid(ENDP1);                          h7 b; w! _- U% |# g
      USB_ResponseIndexO++;
4 `4 b6 f, }: A; `4 H# k! b      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {" ~" a2 R* k7 z  o5 F9 Y+ _3 `* n6 h
        USB_ResponseIndexO = 0U;; ~* ^. N6 D% U
      }) Z5 C# N3 i8 B0 p
      USB_ResponseCountO++;4 Z' [- x2 ~  N/ s! W
    } else {
5 R+ `; g! i  w# X8 D4 _      USB_ResponseIdle = 1U;% y2 |: a* I$ h7 F3 k
    }  
1 Z4 G7 u' H; T, [9 U}7 a9 G5 E/ T, q$ R
: l! v2 I2 R2 f4 A9 T- u
// Called during USBD_Initialize to initialize the USB HID class instance.5 g$ N8 T1 J  {0 y
void DAP_FIFO_Init(void)9 |0 ?% O' E; y1 v& c& }8 L* n
{
7 I1 N$ I0 c1 E  w    // Initialize variables
5 i7 q, \. [2 n3 d0 J8 V    USB_RequestIndexI  = 0U;
& K: i! b! g- K) @    USB_RequestIndexO  = 0U;
3 c0 Z& r8 X' R    USB_RequestCountI  = 0U;# o( }% T) b# M* U  R
    USB_RequestCountO  = 0U;6 w6 L/ u1 V! P& ^; M# P( f% R
    USB_ResponseIndexI = 0U;- F0 L, l- a8 J1 @' D, o
    USB_ResponseIndexO = 0U;
/ B5 \4 t. P' N) B1 H$ y5 E    USB_ResponseCountI = 0U;' p& n, V2 p. z( b2 ]$ g3 U% A
    USB_ResponseCountO = 0U;
1 S* @* J, B9 T; H0 h* |5 {+ ?    USB_ResponseIdle   = 1U;
3 J- P% l/ f* \* L0 V: l1 U' t; S    USB_EventFlags     = 0U;
' t( q/ E, b1 V}% k, V+ }/ r: p( m- {6 n

0 R5 z' X" h8 e9 Luint8_t DAP_Thread (void) {6 z8 |8 t* {, v& s( `7 u/ V$ f& k" ?4 Y
  uint32_t flags;
$ K* a; @$ W- G  uint32_t n;) f# l1 m0 u" l
% t3 e4 a0 W" D& _
  //for (;;) {9 s# Q: l" E1 g7 R5 \* x
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);( A3 z' \( z9 o. `  ~3 C
                if((USB_EventFlags & 0x81) == 0)3 b3 H" [) J3 W1 ]$ G0 y
                {
  \' ^4 ], ]/ o8 ]" l* S                        return 0;
5 j" N9 J; Z* J/ X+ U8 n                }
/ j3 p1 i2 r( e0 Q                USB_EventFlags &= (~0X81);
7 t) {! {% @/ {( K* l* N! w( W) @9 O6 c                : f5 C, t, X' M& p( x  j. Y
                                        3 \# o+ s7 K+ ^# z: g
    // Process pending requests
2 ^0 @1 Z3 }% e& [' w9 w& p    while (USB_RequestCountI != USB_RequestCountO) {
* A$ _. r5 n' Q/ D; L9 g- {% r+ S: ~                //if (USB_RequestCountI != USB_RequestCountO) {
. C- l3 {% W" t  K; h      // Handle Queue Commands
+ Z, q0 U# V5 ^      n = USB_RequestIndexO;
, l0 |1 f' @9 |! D$ a      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
' o; L7 P  S* b* }9 s4 }% I                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
' ]9 l8 I5 B$ R( z        USB_Request[n][0] = ID_DAP_ExecuteCommands;# K( G! f' B/ ~9 l
        n++;5 R  t: J) c  |0 e. X: q
        if (n == DAP_PACKET_COUNT) {+ ?+ g" E0 S) t
          n = 0U;1 g! v% k  n- A
        }9 F  E% W/ {- F/ U& W* f7 H
        if (n == USB_RequestIndexI) {/ ~: T; D7 U0 N7 h' o+ M, M
          flags = USB_EventFlags;  Q& L% m) s. i- ^% N2 L2 h& n6 t
          if (flags & 0x80U) {5 ]6 @7 |) h: S  @9 H
            break;" N) |# J8 d, x$ `% C
          }2 h4 w& q2 U8 x% N
        }
2 J& D2 L% R8 d      }) y% _2 ~( [; G  V; \

# o  j. [7 S. l, a& b: o: {      // Execute DAP Command (process request and prepare response)
/ w: v( |1 x5 ~4 e9 M      USB_RespSize[USB_ResponseIndexI] =
3 y8 Z8 Z7 C' Y" G! w0 \  r# f        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);* C% e; n! F' t/ d( a
( j7 n# ?3 C: H! r. a( |
      // Update Request Index and Count
6 ]4 t6 I# X2 Q, K7 F      USB_RequestIndexO++;
. Z0 I" p2 o9 h# G      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
8 H  P7 S, f- d* A8 x; E8 S+ W) l' A% i        USB_RequestIndexO = 0U;
% K# Y, e8 @6 J3 P, E3 |      }9 G# T2 G9 r- s6 t+ v
      USB_RequestCountO++;9 e6 p1 a* C$ Z/ _
  m+ g7 X6 u7 N7 M: p# d! E5 h
      if (USB_RequestIdle) {
( i5 L: f$ y/ Y9 }+ D        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
, O9 c7 r! l  D/ p          USB_RequestIdle = 0U;- @- ]5 y, l8 B! W
          SetEPRxStatus(ENDP1, EP_RX_VALID);, l7 {- p( a5 }2 Q& r. i
        }
: H; C" n  t% R& ]+ X, Q7 g      }
  x% U. s) }6 C6 V" z0 I' W
6 u( E3 j% E, C0 ?" x  i7 @      // Update Response Index and Count
$ \6 |9 |3 C4 g4 a9 A: s: U) t      USB_ResponseIndexI++;8 D2 ~  C* A4 A/ o7 G9 H6 |" R6 A
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
: X% m( t( d6 \        USB_ResponseIndexI = 0U;
; J+ E. @( Q( G/ A, x      }
# y% d) q! V& Z8 [$ O      USB_ResponseCountI++;
1 a7 U7 f1 K8 z! v, M9 R, F! L5 }' i, ?8 A6 i) O) F
      if (USB_ResponseIdle) {
) ]+ ?0 Z4 y' b. S5 j! {: W        if (USB_ResponseCountI != USB_ResponseCountO) {5 j$ v5 C& t. v: z1 F
          // Load data from response buffer to be sent back
7 O% e2 W- v" q4 N          n = USB_ResponseIndexO++;
; T0 G0 ^6 [7 _# r% j% d          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {  }! l( n, |- Z1 ^- b
            USB_ResponseIndexO = 0U;! r. e' m, m/ ?+ P' A- i" S6 e+ B
          }
) K) _/ `0 v7 o; V: c# _4 t; |          USB_ResponseCountO++;" B! h( l9 s9 t' e- D# z- |
          USB_ResponseIdle = 0U;
+ F6 J) E/ g7 G& I0 F          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
. M# ]- E6 h. h, ]                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
- a5 {# l( J4 o' ~9 |9 j, \( P+ c* G                                        SetEPTxCount(ENDP1,USB_RespSize[n]);9 S( e3 S  g* B, m
                                        SetEPTxValid(ENDP1);0 q+ T9 {* k8 ]) T- P
        }
4 B- p) ~2 o* p: O7 y% _$ o      }, i( N. W- u& q5 s: ^; h: ]
    }
/ r* d* ^% X" I" w* ^" \* W6 N        return 0;
4 g2 `% ?! I, f* W& ]7 p& G}7 x3 l0 f& T9 d$ O3 w' G. t* f

2 ~0 v4 I+ x# T# T: [8 y// SWO Data Queue Transfer
- y# V! k8 N; r4 Z  t//   buf:    pointer to buffer with data
, `; Z' {3 G& u4 m, m5 p//   num:    number of bytes to transfer
, }  o, z1 X- H& @3 Kvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
: L8 k# a3 Z9 `% b' i- H  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
! V' B0 }  w+ x( U        uint32_t a;5 E1 X" {* Y5 ?# I
        6 c6 }4 p! |1 f0 _# f
        if(num>64)
3 k) `1 E$ n; b, L4 B        {+ E! |' m* S& A: O, ~( A. A* p
                a=64;
( f: L" u* I, z6 J# i                TX_n=num-64;
3 ?8 N' @8 M% \0 [                pbuf=buf;, h9 O" s0 V" J. L* j
+ z& ?+ o3 i! O( n# w* i! @
        }else {& s4 e& X, N9 E
                a=num;
& {- \$ t, p% \$ l                TX_n=0;+ ]5 Q- k) B3 V* x: X
        }
' u. h& j3 Z* M! e4 H# i        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);. G" Z: w' N/ G% n+ a
        SetEPTxCount(ENDP2,a);
$ T2 S% W2 X& ?7 \' G. Q) T1 C        SetEPTxValid(ENDP2);
0 o' @; B0 C4 G8 S! n* R+ w}
% x# n( W5 u4 Y% {. f$ {# m& X, B) i2 M3 V9 T/ g7 q+ E3 C
// SWO Data Abort Transfer
$ ~$ S; d9 l6 E) yvoid SWO_AbortTransfer (void) {
2 E  k6 @# ~5 q; h2 V7 r$ z  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));8 [, B; G5 R2 [/ d
        //SetEPTxStatus(ENDP2, EP_TX_NAK);
" a! |5 n  a8 e! n        SetEPTxStatus(ENDP2, EP_TX_DIS);
# y+ C' u9 g7 X" f        SetEPTxCount(ENDP2,0);1 n2 U% y7 ]1 _
        //TX_n=0;
) x' g$ T: \+ F! S}
5 x& B5 l2 t7 f) c6 ~6 s* W/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/& N# n* ~/ l, a8 g' d6 e
) P% }: S8 G% E0 M2 n( V% ^1 i$ i
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处: X( W; h; w4 Y+ H" p/ a7 C
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了7 u4 G' K# W) E3 b3 X+ l
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
3 P) N/ `. `( Z: V* x& o  c3 e  return (DWT->CYCCNT);
+ b* T& o1 z! g* U}, `7 N  J" {9 V9 x. x

, D- P) W2 K" Evoid DWT_Init(void)
! f7 T# u1 D0 m: B; l6 f' R0 X{5 ?0 r6 @5 Z' O) K& q5 A) {
    /* 使能DWT外设 */; A1 z; H) U4 N
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                6 S% Y! K9 `3 |0 o! L
3 u, R# [1 P+ Y* V- c
    /* DWT CYCCNT寄存器计数清0 */; K& A) V7 \0 f: p+ b, E  F$ R2 T1 t
    DWT->CYCCNT = (uint32_t)0u;
3 n. m: g2 l, Z. T% B5 V3 J8 }0 p9 I2 p" J0 T
    /* 使能Cortex-M DWT CYCCNT寄存器 */
2 I$ C. t9 D6 R    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;" D0 v8 Q6 D' A( L9 X+ v+ r
}
" n: _4 J% J  ?5 }( T        
1 E  l3 ?" _, y
4 u7 `1 a$ s& _! Y  d4 }3 I+ k然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
' ~) _' J- s; m/ g3 j( K3 P! m: M! Z& T4 j
然后改为使用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不香么?
! l, t1 A- a; ?/ v  W声明这个变量static volatile uint32_t SWO_EventFlags=0;) F4 o3 J( S) @: X( B: C* c! O3 H
在SWO里每一处调用osThreadFlagsSet的地方都改为如:
5 j# ^3 [7 F+ I9 M5 r* t9 l//osThreadFlagsSet(SWO_ThreadId, 1U);
' T2 }7 [. E* D( s# F/ S) Y2 lSWO_EventFlags = 1U;
( k7 v) ^2 Z0 v) [$ z! i7 i8 T! B& b& H8 N/ d

7 z* V) w3 }3 k// SWO Thread
: i# n0 V: X# g' b$ y/ G5 Q' ^# ]7 X/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
; n1 O9 q% L& a7 D  //uint32_t timeout;. K2 J: |; q4 F' A9 z, P6 ~
  uint32_t flags;
! A, X% a/ n; n% h& u4 M2 O  uint32_t count;
3 O' X) x" |! \# \  uint32_t index;# m, Y$ W. u6 O
  uint32_t i, n;# B- q' I6 q! k: U! E/ g
  //(void)   argument;
+ n" b& ?8 p/ u+ o$ x; `
% p% Z$ K; ~4 q( F8 l  //timeout = osWaitForever;+ u4 F" S; s7 G5 O* ~/ V
) ]/ z3 B! c- Q$ J) I6 i
  //for (;;) {
& h) x" `5 d8 ?: o/ v7 b; r    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);2 U7 Y2 {. j* |9 ~7 H# M
                if((SWO_EventFlags & 0x01)==0)return 0;7 y9 u9 U# v; C2 j$ D- t7 s
         
5 u2 o9 m: _0 R$ S1 y                flags = SWO_EventFlags;- A: U3 y& R9 j. L
                SWO_EventFlags = 0U;
+ a& P  L: V1 Y  n. K  p  V7 I    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {* O) {% n: H- F5 n
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
8 e) P% M* F) j( m                        ;
% t: N( K* y/ Z  d1 `    } else {! }- o6 G; d; y4 l; t! c2 L
      //timeout = osWaitForever;
* i- C5 D( y" h' H3 r$ j      flags   = osFlagsErrorTimeout;
; J$ o. F% t! O# G/ f0 o: p    }
  h; P6 S6 _  R, O    if (TransferBusy == 0U) {
: P: q7 ]/ _# T2 n1 V+ o      count = GetTraceCount();1 A; X# C  w2 e5 {3 h
      if (count != 0U) {; P9 Q- P! K* E3 |; J0 T
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
) O1 E- G8 O7 v. ]( L        n = SWO_BUFFER_SIZE - index;+ I4 L# }' ?4 D2 M
        if (count > n) {# D( m2 a8 d2 l/ K" s" Z
          count = n;7 j* @( |7 v6 U$ a' b% ?* `
                                        6 Q1 Y: o& A( Q/ D( Z5 b. h" g( i5 I2 b* a
        }
9 ^9 ~8 y( \5 M' w5 O6 l                                if(count>USB_BLOCK_SIZE)
; p% l% A% j2 y  [. G                                        count=USB_BLOCK_SIZE;
' p9 K! u2 K9 n        if (flags != osFlagsErrorTimeout) {
6 {$ ~( B3 I; I0 n6 m          i = index & (USB_BLOCK_SIZE - 1U);
. d6 v7 t  a' V/ F          if (i == 0U) {
, G: f! ]# H. R5 [) `7 n4 `$ a6 k            count &= ~(USB_BLOCK_SIZE - 1U);
1 _' ?% t7 z9 t          } else {
( Q: [+ p7 J4 i. n$ W            n = USB_BLOCK_SIZE - i;! z6 c7 p$ ]( h. s, d
            if (count >= n) {8 N  p/ ]7 I/ A# p: ], X$ x$ H
              count = n;) u2 ?3 ^) x" k; W; Y
            } else {* g4 E6 Q9 n; V: L3 p6 C
              count = 0U;
% l' M# \& F4 L2 X; y& _/ V            }( |1 z+ H5 p; `5 J; [$ Z
          }
, u# O  |$ I4 R, g: q9 D        }4 S+ Z* ^1 A9 z8 c" Z
        if (count != 0U) {& x  G4 Y/ j1 ~$ p
          TransferSize = count;
. k  L) h' K* _; Y: T: i          TransferBusy = 1U;' a( M6 V: y! N3 l! h9 _, @
          SWO_QueueTransfer(&TraceBuf[index], count);9 O0 ~$ ~2 T5 v
        }
0 e1 _. |0 h$ q6 C3 V      }% B6 Q5 X) z8 ?. o0 ^& g0 H
    }9 W, e7 T% Q" h' l3 q0 I  m
  //}; L0 F, E/ d+ X, i
                return 0;
) ~: }4 X+ f2 E/ n- y% d# {+ \2 q8 E}
9 @* X# h9 }, S! G& _利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
0 j9 @7 _/ g! D$ s% r#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).0 ~: i2 I9 ?/ d- Z: k0 F+ b
static volatile uint32_t SWO_EventFlags=0;
' o2 v9 ?6 _  u9 Q+ x( N/ ]3 r, G$ u4 Rstatic volatile uint32_t timeout=osWaitForever;
0 l6 P& J3 r  {8 @, [# a6 ~static volatile uint32_t timeWait;( U; F, m2 E$ z5 ^1 D1 T8 K
函数改为这样/ B5 C% c+ P$ W# I3 j# d
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {/ t$ ]! p; ~- v6 a5 ]
  //uint32_t timeout;
0 o& v( @  K/ N) Z# C9 y  uint32_t flags;
* c. m! z1 i! ~# @9 j3 ^  uint32_t count;1 D" H6 P, M- T( S
  uint32_t index;
7 G% x8 y; |7 o! g  uint32_t i, n;
/ G$ \4 A. r2 S- n3 g9 C- ?  //(void)   argument;8 y0 g3 `8 a# N! P

" l& Q, i9 A9 B. \: u$ A: ?- H  //timeout = osWaitForever;
8 L  v. f/ y; F/ L" N
6 X8 y3 e1 i2 }8 z3 E0 ~  w6 b  //for (;;) {( s+ }, i) @5 e) _6 m; h1 C
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);6 r4 E; b# r2 C6 `7 T8 G2 @
                if((SWO_EventFlags & 0x01)==0)2 M% N& c3 k* M* h% v6 g
                {# ^3 f* Z& ]9 f9 j( y0 T  [; c6 i* l! O
                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了) J. O8 f0 K, G( ^- Q, m. t
                        return 0;. q8 w: ?1 `) y) n" e  e! [4 s' e) z
                        
7 ]2 F( i  m* a. q) L8 I                }: Q/ n* X' W3 x% o) v: l& d! i" h
         : Z/ l+ |6 f! A1 V: W& Q
                flags = SWO_EventFlags;
# T3 b1 |3 `% d) a0 Z( i                SWO_EventFlags = 0U;
: R+ d2 C! Q4 S" e* I, r    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
. ^0 S3 U' A# b& f3 s; Z* D8 M      timeout = SWO_STREAM_TIMEOUT;* A: R& d. T6 q1 S' y) J
      timeWait=DWT->CYCCNT;
( e" G' K2 d1 d! s    } else {; H+ V4 ?5 p# s9 y3 ]1 W* n
      timeout = osWaitForever;. ]4 Y4 @$ P/ z+ Z8 U. y. O
      flags   = osFlagsErrorTimeout;
# N9 a6 h" Z/ s/ H% i0 ]* Q    }4 F' \+ g  X+ V* A- Z
    if (TransferBusy == 0U) {" x9 I$ f. q2 q( J; Q7 t8 \
      count = GetTraceCount();
3 `% H" B) u# K4 {) p! t      if (count != 0U) {
! {1 g+ b# ^! [/ s. y! z1 X        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
8 m* ^9 ]  ~' y0 ^$ Y        n = SWO_BUFFER_SIZE - index;: c$ g4 o& f6 C% V7 |3 M+ `
        if (count > n) {8 `: a1 y$ q4 \
          count = n;
) r  v( s2 O3 i: o3 k, [9 L                                        1 O! L) U. y4 G6 ]  t" t
        }" m0 m7 c# t7 o+ S1 I; N1 D
                                if(count>USB_BLOCK_SIZE)
- O- T/ U( K6 i) y5 e5 m                                        count=USB_BLOCK_SIZE;! Q! |& M% X0 v+ w: G6 O) u
        if (flags != osFlagsErrorTimeout) {6 O2 G* K" }9 K+ @+ C  W. s' \/ X
          i = index & (USB_BLOCK_SIZE - 1U);/ D4 T+ e! H5 w, x& g) [! \- {
          if (i == 0U) {. e, \; x3 H: C6 G' e
            count &= ~(USB_BLOCK_SIZE - 1U);
, ]; x; s8 S, C* O' @          } else {
$ G  _# I  A! y9 ~& N            n = USB_BLOCK_SIZE - i;
. d( |7 @3 m/ k            if (count >= n) {
9 C  ?1 j4 |8 a. D* n1 q* h              count = n;  C3 l+ c" m0 }
            } else {
) h5 J' v8 P1 A& p3 B4 G" j0 R) V4 F9 J. M              count = 0U;& w5 `; ]4 I# j  x3 t4 p
            }1 [7 i4 b% X  b# w* G' Q3 `1 }3 n
          }
! n  y; Q; v! {, U' E! x% T        }% Z1 m7 t; N& ?( H* [/ f- f
        if (count != 0U) {
, i2 R  C7 N" ^) e: I. N          TransferSize = count;
, o# L9 A  c2 ^" w% L          TransferBusy = 1U;
0 h% e  s) D) `3 ]& ~          SWO_QueueTransfer(&TraceBuf[index], count);! @* j6 q) E+ F! H, G( h. M7 ^6 B3 ?
        }# I+ i" ?* M6 d2 Z* w
      }: y6 V$ h, Z$ r8 `/ [
    }. N! ^4 E" O7 F, m
  //}8 ^8 j2 R* t2 A* N) d( \
                return 0;
9 S( _6 n9 `1 h. p9 R' F9 O}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了
( d+ G9 @1 P+ P) N' R) T+ _
7 {: K9 j$ j4 lCDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率
& W: S5 \5 z( P6 J7 k; \" \: c, I% L8 x7 }4 w( l

) N# L8 U, d0 L( L6 Sint main(void)! y! w; }9 g: D
{
4 p& ^* l2 _, B* t  DWT_Init();
1 c5 t1 {, H2 F2 q, ]# x        DAP_Setup();3 k: w- P% Z( s  e4 Q" P+ x! a
  USB_Interrupts_Config();
! w6 [* |3 i" k0 v& B  Set_USBClock();* I9 W+ W: d: Z
  USB_Init();
4 m6 k/ f" S4 v4 z/ \2 d6 U# L+ c        //TIM3_Init(35999,0);
0 `! m3 E" h1 i        //TIM_Cmd(TIM3,ENABLE);, I$ `) i! n. j/ ]6 @5 Y( V5 O
        + p5 [2 G  {2 W1 y- p0 w# ^
        
+ D5 ~& j" H/ ]0 w# V6 U  while (1)
2 Z, C/ \) m7 Y+ k( y  {1 s! v& R7 q8 g$ q9 C) k
                DAP_Thread();
& t% e+ l7 c* @7 M* P* R( S+ _                #if (SWO_STREAM != 0): I3 [4 e! M5 w% N" ~1 M
                SWO_Thread();0 P! p% m; \5 f' ?! _# e3 P: }
                #endif6 m% _! x+ m6 x8 F, u
  }8 H% @9 ~3 }+ o# T2 p# R
}: c1 H6 P3 I  b3 T/ `3 ^

3 Y7 X1 O2 B; B* u对于DAP_config.h的IO配置我是这样弄的
9 ]- U% u7 Y9 a( [  E0 e///@}% f% s6 N6 i0 f' N
// Debug Port I/O Pins
, W& F# {# I; b5 q
. U& k0 C7 h$ _+ E0 {// SWCLK/TCK Pin                GPIOA[6]. D: _" u% ]3 j  _
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
. y4 Q& P$ d! p, {$ M+ M+ B* B#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
+ ]8 j( }) |7 o- s( Y1 Z2 C
! V* `6 d' ~( H// SWDIO/TMS Pin                GPIOA[7]7 Z' E% f1 Z7 G0 Q5 H( Z
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C! d" W! l, W* i1 ^
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C- G( ?! _4 h) k2 y  j- Q

/ i1 j. D9 t# v' m// SWDIO Output Enable Pin      GPIOA[7]
' ~2 J) |7 E5 r! n! ~#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \. B$ S" W, c: |( \) S
                                                                                                                                *(uint32_t*)0x42210070 = 1; \. b* `. v0 k3 f3 Z
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
9 K' S8 w# Q; j1 p                                                                                                                                *(uint32_t*)0x42210078 = 0; \
* C$ _9 j& F$ u5 p# o/ a1 _                                                                                                                                *(uint32_t*)0x4221007C = 0;}
% Q9 v5 W; Z  @' v; N2 ^& a$ z
' t- h; Q5 ~( w9 |; z#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
- `% k: ~' `0 p& ^4 y                                                                                                                                *(uint32_t*)0x42210070 = 0; \
# E) @1 d, y/ g, U' ]7 k                                                                                                                                *(uint32_t*)0x42210074 = 0; \+ }# E8 [6 _8 E* w( ]
                                                                                                                                *(uint32_t*)0x42210078 = 0; \) Q4 u0 e: u' |9 A7 V
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
# |; ~6 N- f2 A7 Q) N# n, U6 Z3 a0 D& r
// TDI Pin                      GPIOA[8]- |; o3 N) ]. Q' T/ C  e
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
& P; k" H3 Z. Y& e#define TDI_IN                                     *(volatile uint32_t*)0x42210120
( O' N9 j  n/ {/ {1 m0 r  H6 T. x2 Z  N' I
// TDO Pin                      GPIOA[10]
, [  K/ j& y5 w+ i3 q0 A#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
1 e  o- w. T+ a, z#define TDO_IN                                     *(volatile uint32_t*)0x42210128
7 Y& i2 c) ~: J# g0 r1 U5 }# E& t; f  p2 x
// nTRST Pin                    GPIOB[3]! e  j* ]  P0 Z7 b1 u
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
$ ^0 Z8 m5 m. Z6 M: x" @#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C) w  Y+ r* F' E9 p

0 ?! c8 Q5 w& P. l, b1 d1 G/ q// nRESET Pin                   GPIOB[4]
7 u/ u8 N, e3 @& _4 ~#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
; p% f6 C) v5 h. Z! S3 Y; K#define nRESET_IN                                  *(volatile uint32_t*)0x42218110/ ]2 ?6 _4 Y) C
+ [7 [& K  J& b$ E
// nRESET Output Enable Pin     GPIOB[4]* f% ?( Z3 d" ^6 @
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \  k+ y- O* R/ v! B, w
                                                                                                                                *(uint32_t*)0x42218040 = 1; \
' l7 l7 r! n: Q9 w                                                                                                                                *(uint32_t*)0x42218044 = 1; \
' R% q, X3 u. D5 ?+ k                                                                                                                                *(uint32_t*)0x42218048 = 0; \: h9 [7 ~/ M9 M/ S% [' x' n
                                                                                                                                *(uint32_t*)0x4221804C = 0; }
/ \3 M' S5 U6 D$ j. E' l$ l( I
2 f# N3 d/ J. T. E7 J#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
. p2 z( N$ n9 r: h                                                                                                                                *(uint32_t*)0x42218040 = 0; \2 H0 e) t8 C# |4 x
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
( r& j7 K5 q" C/ |9 D; l) j# [' l                                                                                                                                *(uint32_t*)0x42218048 = 0;\  D1 o, O& T! D+ r& s/ C7 w3 n' I% d/ P
                                                                                                                                *(uint32_t*)0x4221804C = 1; }! n/ j& h7 |% {+ @4 x

+ d. k; m, s& O/ b& r! B  K1 W' M
8 o& i0 L3 d1 f" d8 I) v0 r. g// Debug Unit LEDs
1 z% e# K: |1 ?' W& y
6 G: \$ L& ^: }- I- ^( A+ s1 Z// Connected LED                GPIOC[13]
' m: ^+ p$ H/ ?# Y* u#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4# h0 R; O- w! z% R
#define LED_IN                                                       *(volatile uint32_t*)0x42220134# x4 D( ]# p  }: y/ F0 E; y, O; Z

; @1 b6 d) c  X" d" V#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \: x% @! Z+ d* z: s1 Z3 \
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
# v1 l: M6 e; }# ^$ d( n/ E6 d5 r7 o2 M                                                                                                                                *(uint32_t*)0x422200D4 = 0; \
: G0 q- \6 d6 `! }                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
) y% J9 A+ r' p; {                                                                                                                                *(uint32_t*)0x422200DC = 1; }" c! q- m9 c1 P! {" ]: l
// Target Running LED           Not available! H- c7 b+ H* a! C) M

' S8 n6 E5 j; D  b; e% R* }// SWCLK/TCK I/O pin -------------------------------------
! \# R' ~: T# `  L$ |+ T
/ ]2 s, \8 x, O3 I2 ?/** SWCLK/TCK I/O pin: Get Input.' M* s+ B7 V% i8 c8 v6 g
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
  F' G# T! G; R*/6 I4 C. x  q  ]; [  o
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {' d- Y! P- S9 q9 k. y; A
  return (SWCLK_TCK_IN);$ \" J" \% ~6 x* x1 {9 W
}
  H; s2 D. m. j# H- q# h2 J. u+ w! x( j
/** SWCLK/TCK I/O pin: Set Output to High.: F3 N" F. {+ r7 ^# M
Set the SWCLK/TCK DAP hardware I/O pin to high level.
7 M! ]# d2 `2 x4 e*/5 B: q2 G3 r% d" p. h' P$ }: L3 b
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {, d4 g) v* _. I4 U! b
  SWCLK_TCK_OUT = 1;9 G+ v5 |  u; v0 I; z( n5 q: ~# |2 s
}
. X- G, X( j* y. a; R) {" D+ ?3 w# M% _' T" i$ ?
/** SWCLK/TCK I/O pin: Set Output to Low.& F7 p* U; P% u/ \7 Z
Set the SWCLK/TCK DAP hardware I/O pin to low level.
7 W. z; b4 k7 J6 u*/
! w( a' V! z% J8 K9 y__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
, o" F3 |# V/ p5 t% i+ W+ k  ^# `# o  SWCLK_TCK_OUT = 0;/ N) [, ?* M+ o1 m. p2 Q
}
* {" {. }5 S! j/ m
; O. P" m; u! O1 e" O8 g! U7 T$ a- @* u2 j
// SWDIO/TMS Pin I/O --------------------------------------
2 y; B: O5 {! w7 O) N6 O: ~( a0 U8 I" [4 T5 c+ q
/** SWDIO/TMS I/O pin: Get Input.
9 V$ i: K/ u6 [- R3 ~) Z\return Current status of the SWDIO/TMS DAP hardware I/O pin.. S5 Y, q5 {7 K, s
*/
/ l, |' h/ l1 h0 z$ k) I__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
7 f5 j- ^0 g5 y  return (SWDIO_TMS_IN);
+ @+ v; J, X8 V& {, o}! r8 m1 f/ a$ C; r# p% T
1 Z2 P$ Q5 [& s+ K% p  q
/** SWDIO/TMS I/O pin: Set Output to High.$ i' N0 n; n: C6 \1 E0 g/ Y& f
Set the SWDIO/TMS DAP hardware I/O pin to high level.$ ]0 z& D8 W8 J" o; Z5 V! D
*/
; X% ^7 l4 D  s* I" a0 E__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {8 I, }9 C3 \( B! n6 a
  SWDIO_TMS_OUT = 1;- v! @6 w2 k; H8 P3 a# l7 i
}5 ]. Y( c9 X4 K6 C% ]$ a, J
2 M7 Y  q3 m, ?2 F
/** SWDIO/TMS I/O pin: Set Output to Low.% U: P# R0 i+ x' k1 v* K! z
Set the SWDIO/TMS DAP hardware I/O pin to low level.
  c' C8 o, v/ u1 W) ~6 h*/7 `, H  T9 A$ N
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {
. c$ x8 G9 y- f9 t; F, J  SWDIO_TMS_OUT = 0;9 I6 u( G( g3 C- M
}
" I) u2 Z# L& S; g
1 w! Y0 Q" Q+ T, Y9 q3 y9 ]( ]2 p/** SWDIO I/O pin: Get Input (used in SWD mode only).) t% r7 |$ [" T) F, i1 J6 h
\return Current status of the SWDIO DAP hardware I/O pin.
, r$ [- d; L0 ]*/
) b, ~# L% B2 Z: ?__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {4 o' n7 L  ]& d: h8 d9 m
  return (SWDIO_TMS_IN);' s% {& X% {; w. t$ ], f3 _
}
+ J/ X6 e3 `5 E: I" y0 ]$ L. H. F4 z4 D" m% \( o" M7 g
/** SWDIO I/O pin: Set Output (used in SWD mode only).
6 p" K. T, M# h. E\param bit Output value for the SWDIO DAP hardware I/O pin.' p( I8 E! X1 O/ p7 }0 P6 T- e& T- P
*/4 e  A) D* A. S' P# q$ u
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {. Y' \5 q/ F) i4 j; y) G# R: c0 O! v
  SWDIO_TMS_OUT = bit;
" @- S$ M" P. o  b. l' I* l}" U7 ]+ O& U: O/ g

; q  z8 C! J* t& s& |/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).8 u/ z( V$ R+ b
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
" V- L" H  |2 {# T" m! Tcalled prior \ref PIN_SWDIO_OUT function calls.
& P* s  H$ e5 g0 o% e8 `*/
) c) T- t( T$ f* A/ A, m3 d__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {5 _8 w3 W% K. G9 C
  SWDIO_Output();
- R4 ?5 ~  z# D& C}1 h7 M0 e7 b' j1 a! }

9 ?: [6 _" e" N" P1 [  K: w4 t/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).' X$ g5 B! \9 M  {' p' f
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
8 ?2 g2 B" `: d: M& Ucalled prior \ref PIN_SWDIO_IN function calls.
/ |' @: q8 y6 x$ q0 ~" K# I) p2 m*/
( _$ o! `- `* T- F__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {$ V9 O& O4 n! F: X/ J
  SWDIO_Input();
) B* }' c% c; T& \1 r& V}
. J, [3 I5 @; d# R8 V8 J
( u# [6 x3 G. H楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
7 t# \' V6 X0 Z4 n3 ?即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下- T! |2 R+ P% Q" b! ?
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似技术帖

官网相关资源

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