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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。
2 f  H# C. R6 v3 v4 S# T7 p" E
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
/ c6 g# ?: Q7 q' E除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

; Q% L( c: P) _! B3 c8 {我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。8 [" U* C  `; ?: A

, ^9 Y5 T5 {1 ~! `  y' i6 v! l7 p软件复位是另外一种情况,需要向目标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
! D7 J  T; C8 K7 @& U可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

8 m: }8 @' Y% w0 A0 ZnRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。* H( ~! Z8 h% Z3 J4 s) b' y
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。& ~1 l( `! @5 {
" {1 O: d( N( l- u
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 * O) C" t3 r7 Z7 N( `  |- e2 @
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
: i' X5 e5 J9 ~& @5 _1 g; A0 e# v# I, O4 u( u
! ~' R2 @. i* R5 E! C4 V6 D
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?+ V5 Z' |* }+ n
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap ) b% A) ]0 O& W' k8 Q) g% }& A9 g4 _
起点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 b: [9 N2 ~, r' g3 X/**
; h- [; W" @( G; W0 v& Z, l( G) E9 u  ******************************************************************************% O3 ]  @  B8 R8 _4 E5 l% O
  * @file    usb_endp.c
7 W* O4 {( i* c- G4 ?& j8 R2 \  * @author  MCD Application Team
- A. O! d/ \3 `" j5 s4 u  * @version V4.1.0
0 W9 i- j& ^, v  * @date    26-May-2017
7 N4 i! j" J; S" |/ V8 V  * @brief   Endpoint routines  }. f" m* A* o) M0 S$ C
  ******************************************************************************1 g3 {4 `7 i5 D1 r3 A! t. _
  * @attention
4 j' |7 j* {2 p7 P% N/ W# L  q9 N0 f  *
6 C) N$ U2 w/ D6 a0 w) m8 s  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>: K$ c1 K9 \: q
  *8 d& ~& Y. \. @: \/ F9 L7 Y: j6 E) X
  * Redistribution and use in source and binary forms, with or without modification,* W8 L4 V+ W# t' D- {
  * are permitted provided that the following conditions are met:
. @7 L8 m- J) n2 I8 T9 }$ g& R, f' f4 D  *   1. Redistributions of source code must retain the above copyright notice,7 M) X5 N3 `+ }8 V0 r, w# c2 A
  *      this list of conditions and the following disclaimer.
$ w* d0 `0 W" D$ Q1 A- g  *   2. Redistributions in binary form must reproduce the above copyright notice,2 g8 J/ K. P9 F" V
  *      this list of conditions and the following disclaimer in the documentation' x. P' z. T) p5 L% `" R0 o8 w
  *      and/or other materials provided with the distribution.
- y7 m9 e( y3 H1 f$ u  *   3. Neither the name of STMicroelectronics nor the names of its contributors, D5 o2 k; i' E' C
  *      may be used to endorse or promote products derived from this software
* B8 D/ G1 ^" t3 N+ f, ~  *      without specific prior written permission.  _  N+ a$ P5 x! B
  *8 ^- Q: q# c' _. }2 m" R7 g; G
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"& D/ V1 k' e' `' P+ P7 V5 u
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3 w  g! n7 H- I$ s$ \# w; t: E6 n  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE( [+ L$ i" Q0 T0 M& p* \2 @6 j6 \* g
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE' N/ {. H+ ~1 ~5 j& P) t  ^0 x
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL3 d; |( u6 E! _  p1 }8 P
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
( U; C; `( R3 l; ~  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER, {( i/ i# B! }" I8 ~; q8 S
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,9 ]1 W* V' }7 b9 i* K
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0 B. I3 x. F+ q& M- c9 b+ O! o  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/ q5 x) x7 E( U# v- W" Y; a3 w  *
& k1 v# Y8 S' U8 S  ******************************************************************************
) P! i7 _. R8 b# a+ `  */. z! D. P; b. S+ O- r% n

- f* o6 [6 w  {7 D
) F) v( h* V7 ?) F  e* G9 x" _' {/* Includes ------------------------------------------------------------------*/4 a1 E8 u- }+ O/ z$ D2 N
#include "hw_config.h"
. x0 z0 N  q6 U7 k; L- E#include "usb_lib.h"
& g, L: y9 Y& I3 e* w4 g* k  K#include "usb_istr.h"8 I) P6 U6 r2 S4 Q; {4 k0 T
#include "stepper.h"
6 X6 R1 r- w( n: q, {#include "string.h"7 }0 k8 a8 i1 O  v

6 t2 T" Y! ], `4 a3 C* `6 J1 A#include "DAP_config.h"  y# i5 q6 _9 }" i9 m3 k
#include "DAP.h"
, h7 G% e4 `* I& a" [
, C3 O% G& \8 t/ p$ c% B& i" a. ^9 c( i) r; K
/* Private typedef -----------------------------------------------------------*/
& U# J5 P8 [# E- @& ^3 R/* Private define ------------------------------------------------------------*/
- k& G) L  L; W8 B/* Private macro -------------------------------------------------------------*/
9 V1 a- L  `# N/ z/ _* h9 c/* Private variables ---------------------------------------------------------*/
: B  y0 _0 `4 ^, [. F# nstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In& \" P$ V; K7 p; Q, t7 p
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
5 w- n1 H6 l# y1 G% L9 C6 z, Dstatic volatile uint16_t USB_RequestCountI;     // Request  Count In
: r7 }6 E6 w8 _* q8 }; x$ Nstatic volatile uint16_t USB_RequestCountO;     // Request  Count Out' R8 e/ Y! G2 c- W5 h0 r/ O
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
4 m+ b/ W' _4 o( ]: L$ ^
: G# s: Q0 v) J8 _static volatile uint16_t USB_ResponseIndexI;    // Response Index In+ H7 Q( n: E$ Z& b
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out8 S* S% t6 J& q9 \  U4 Z5 g4 [( l
static volatile uint16_t USB_ResponseCountI;    // Response Count In" R) d8 D" V& |- Z4 n* i# |4 l
static volatile uint16_t USB_ResponseCountO;    // Response Count Out
2 V( E1 K: x9 E: E$ P/ Z' u  Zstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag" I( Y) Y& e, Q4 g6 O# U- C
static volatile uint32_t USB_EventFlags;
( {( v5 `) \* B& e" R  x
3 I  s/ g$ q7 c* p9 N+ Qstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer3 k* t5 Q; n  B) F$ I
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer8 \% g9 L- @, J0 I3 Z, i
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
; c8 F8 _2 z7 P; D( Y* `  K
5 n. s# a, _9 J9 e0 [0 m/* Private function prototypes -----------------------------------------------*/( a6 y2 c. g9 x8 A) K' s/ X
/* Private functions ---------------------------------------------------------*/. N# D% C7 _; ^7 e2 Y. _
/*******************************************************************************
4 A' f) p2 Q9 S% I3 m6 P* Function Name  : EP1_OUT_Callback.
" z2 x6 t+ N7 `# S5 v0 B* Description    : EP1 OUT Callback Routine.0 w- j$ T& ~& @' M
* Input          : None.5 f6 T5 d- q  Q- U) C; E( A
* Output         : None.; t: z0 j2 Y7 P6 F# ~+ m
* Return         : None.$ D8 Z# P+ c" R2 P  C! d
*******************************************************************************/
1 Z, w  y: q9 K$ Wvoid EP1_OUT_Callback(void)
5 h6 D+ a6 w+ \{. X5 s  m: H$ m' e! t
        uint16_t n;, A8 i' V( u- T- S  c5 e+ O: l+ z

" H' W9 z& J5 `( L        n = GetEPRxCount(ENDP1);# D8 X3 J5 T" W- k& q
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
2 g# `9 v8 d6 ]" D9 b1 B8 g        if(n !=0){6 ]1 b2 I6 ]4 _+ I  W9 U, D  c+ m
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {) W+ g; c3 V: j* c' y7 {
                        DAP_TransferAbort = 1U;
& e% [& f+ r% L  P                } else {, y) u+ J( m& U& y- Z
                        USB_RequestIndexI++;
5 n2 v, k0 m/ E  ]1 H' {0 w0 T      if (USB_RequestIndexI == DAP_PACKET_COUNT) {# p2 o+ I: Q9 [. D6 k
                                USB_RequestIndexI = 0U;
2 ^4 f2 u: v% i2 O7 U      }) q( n% h& y9 ~" f
      USB_RequestCountI++;+ H& f% }3 n, {! x" C
        USB_EventFlags = 0x01;
# N' Y. i" h% b4 G/ C4 R    }
  ?0 Y, i! E4 T- E        }        + X7 j. a; w: N$ `4 t! S# G
        // Start reception of next request packet
, q4 m; n8 [! {5 G9 ^        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
7 M; R# ]3 S' X/ k: k% a                SetEPRxStatus(ENDP1, EP_RX_VALID);) E% }% ]' l: U' k. ^) c
        } else {
" {) R$ ~$ K3 u# z' P' p                USB_RequestIdle = 1U;  `& `3 ?( f6 T9 T+ u2 }. p/ q
        }                        9 e& L7 {$ d  M6 B
}
2 ?9 m0 ?% U- K# C& e+ s- F
, A5 s. L2 a. @$ y$ S/*******************************************************************************
; t) u6 m, x9 p  j, [" N% L* Function Name  : EP2_OUT_Callback.
! t, T3 o: A' ?& h* Description    : EP2 OUT Callback Routine.2 ]) d) P6 m% T  R0 ^
* Input          : None.% E$ l# k' R/ K: M
* Output         : None.1 F% t! ?, s3 i" C
* Return         : None.
9 s( k6 B4 n$ V*******************************************************************************/5 }& ^$ f6 Z/ L9 u
static volatile uint32_t TX_n;
4 i. s9 Y2 P) @6 ystatic uint8_t *pbuf;
5 m1 Y/ W2 y1 K! w- g& p8 R# |void EP2_IN_Callback(void)
) V( _" }6 x. p8 i9 i4 Y4 ?0 D{
7 s5 G# t' N0 a2 F! x        uint32_t a;3 ~8 x  w) Y' D8 w% f
        if(TX_n>0){* f7 e6 _. e% r$ @% c8 T
                pbuf+=64;$ x8 [& ?" O6 [0 B( S9 v7 }& [
                if(TX_n>64){3 H. j. @7 |; q$ q
                        a=64;
- R9 G, E" b- a2 L1 K                        TX_n-=64;
% S, {3 ^! {7 A. J                        ' e8 z: J* z5 q
                }else{0 l7 P/ o% a) j* i
                        a=TX_n;
5 F2 y  H. H! k" X0 e0 T" n                        TX_n=0;; v  [  M) J- u
                }
+ ?! H$ I8 t  k+ `4 ^               
. F' U3 h- c& p& \2 w7 z+ {8 Z        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);6 c$ F- T. y3 q  H0 \' E& W
        SetEPTxCount(ENDP2,a);
3 k# G/ _/ }. K8 j                8 y! }/ B! _4 m1 R
        SetEPTxValid(ENDP2);
" X! n! F/ v+ h# h3 H5 M$ n        }else{% D8 T( n! k" v- L" e& V
                #if (SWO_STREAM != 0)/ N7 [  d* p+ R9 S0 I
                SWO_TransferComplete();
# k7 K$ d) y& Q2 n. Z& y                #endif
' V$ R9 w5 |. P' g) J) P% c        }
  x! v. _: x& ^9 P7 N& M}; U5 o5 U3 G4 m/ G" M  A
% q* @: U: c6 C( _" ]8 W8 {, h) N( O
/*******************************************************************************0 g/ T/ }* H6 d
* Function Name  : EP1_IN_Callback.
0 o3 \2 t% C1 c2 a7 v$ ]7 t+ \7 V* Description    : EP1 IN Callback Routine.0 ?  C3 R2 p$ X5 j& u
* Input          : None.
9 o: _) U+ N6 H* g2 V9 _7 \* Output         : None.
9 ?7 J# L8 ~) j+ d* Return         : None.
: m6 h" G7 b- x" O& P*******************************************************************************/
; Y7 w! W7 j) Z! x4 W7 q1 U3 d5 dvoid EP1_IN_Callback(void)6 u/ A, H/ U% z2 P; U' u
{' e2 R7 T9 e- i; D% K- g
    if (USB_ResponseCountI != USB_ResponseCountO) {9 T( M& F' b) Z# t8 E+ c/ C4 X
      // Load data from response buffer to be sent back9 @' I3 Y6 x- s
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
1 T) W1 w7 N" T! o: ~                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
* @+ r  u8 a( H& b; t% {2 ^                        SetEPTxValid(ENDP1);                        
- z. D* v; h5 F, ]. w( T' I      USB_ResponseIndexO++;; t) v  {& m  t
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
7 T9 s& h9 O: k1 A& i* E        USB_ResponseIndexO = 0U;* a; E9 r* s+ X2 X0 D
      }1 n5 a9 U! ?2 G% O
      USB_ResponseCountO++;
0 u: L/ @. I2 l0 J( X    } else {
5 M1 O5 h: \5 u9 r. ~      USB_ResponseIdle = 1U;
/ r" j6 n3 v# A6 q! H    }  
2 [7 A0 L/ Z7 @9 V' ]0 K' M3 n, c}
+ a: v' z, T4 g0 a( A& f( F# p$ S; a( J1 ?2 N7 c5 N+ C$ g
// Called during USBD_Initialize to initialize the USB HID class instance.: l6 ?( z% [, ?7 I, m2 E
void DAP_FIFO_Init(void)
' o7 w. B6 ?1 Y) ~{" p. n% h0 m+ q) {$ Q
    // Initialize variables
$ \, T- `) l! Z% O6 |+ Q. l    USB_RequestIndexI  = 0U;  ]. j2 \0 }+ O2 S9 D5 W
    USB_RequestIndexO  = 0U;
/ J2 G; t* o8 K# U    USB_RequestCountI  = 0U;
/ T- ?; G* \4 q  @# z. g    USB_RequestCountO  = 0U;
7 b) m0 }; f* A    USB_ResponseIndexI = 0U;- C, H+ Q# m2 ^& [5 w
    USB_ResponseIndexO = 0U;- H7 ]/ A, s- Q
    USB_ResponseCountI = 0U;
) l) B6 ~4 F. |* v8 I& a    USB_ResponseCountO = 0U;
9 Q: `5 ?) a! Y" d! y    USB_ResponseIdle   = 1U;
, u, F' }9 D% K3 |    USB_EventFlags     = 0U;
0 x, c, I4 e5 J! I6 j+ [}8 F; |2 P$ g& j1 e- Q0 K

, \, W8 {0 y4 }3 W5 fuint8_t DAP_Thread (void) {
8 a: \" W9 I9 L  |/ u  uint32_t flags;
+ K% R. j; `+ O3 F  g; o" M  uint32_t n;  U* \" ^# ^) |/ U8 |7 I, j1 g3 [
3 J/ W- Q* ~/ K% q- _9 B8 H8 ^& B$ b1 |
  //for (;;) {' C% W  u  F7 H: z
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);# O! T& ^7 K6 k
                if((USB_EventFlags & 0x81) == 0)
" F0 D2 F# y2 j6 X3 |, O8 i                {
' m% o0 [/ a$ q                        return 0;
- p2 G" t- R! m, ^" z                }2 b, R) l) l1 C8 Y9 ?2 g, T+ H) w
                USB_EventFlags &= (~0X81);
9 f# I' o& f% a  x               
3 ~. n/ F) O- z, [' v, v& ~                                       
( Y* h+ l% X2 X    // Process pending requests' f" w- a4 i' k$ _
    while (USB_RequestCountI != USB_RequestCountO) {
5 q4 d- ~* ]* V                //if (USB_RequestCountI != USB_RequestCountO) {# b2 h- |/ Q- R
      // Handle Queue Commands1 h* w/ e2 C1 q+ ~% y+ K4 h
      n = USB_RequestIndexO;' ]/ [: ~! c! W, ^- ?
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {# f) D/ Y) ^6 x6 a6 w
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {) a6 ]$ I' o- p
        USB_Request[n][0] = ID_DAP_ExecuteCommands;
# ~. E4 r% x/ d$ K; b        n++;- T' P  C: Q# e; }+ e
        if (n == DAP_PACKET_COUNT) {) q1 q  k6 i' A! L8 u
          n = 0U;- i) e  P5 B  ^( h( W! R' {, ?
        }+ u/ B, q8 l* U. _3 _2 m: v) {6 \
        if (n == USB_RequestIndexI) {7 b7 U5 F2 _, n4 V. j
          flags = USB_EventFlags;$ b/ y) t2 {; ^  F% z; l
          if (flags & 0x80U) {
$ N6 H3 i/ R/ S  o. S/ T; B8 @  H            break;& F; A, m! [% J* `9 u# S
          }
9 |, H6 y: U! W" w" x: h        }
/ q+ u4 B: n- f" Z      }" T& B+ C2 b# L( [) _9 k! o& C
: a. R& v; ~! y* `. P. h
      // Execute DAP Command (process request and prepare response)9 W; c$ j+ B! m
      USB_RespSize[USB_ResponseIndexI] =
0 o0 F, c$ u+ f" E  S/ B! I        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
" b' `& {; E1 `7 o  u5 M5 c3 L$ I' k
& E4 E8 d; {4 l6 O6 y      // Update Request Index and Count
% p! u5 k& h4 z  O! S      USB_RequestIndexO++;
, Y7 Z: b9 y! t3 f: }* S" U      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
: Y$ r3 c8 _% Y- ]; B        USB_RequestIndexO = 0U;
' N1 t9 `# J, o# x5 p. S& O      }, m# P. y3 _5 ^1 z& c! m2 N* U! c
      USB_RequestCountO++;
7 B  z! H2 Q. K* {% I% a6 K9 R9 d% c7 f6 R0 Q7 }8 j
      if (USB_RequestIdle) {
* }/ G/ ~, p. h6 u" A& @        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
+ E, Z, _) s# e" S          USB_RequestIdle = 0U;* `, t4 n" U2 p, X  T5 b
          SetEPRxStatus(ENDP1, EP_RX_VALID);+ m) j6 W( H1 B8 M
        }9 }: F* L8 D2 U+ p4 o, j( {
      }
/ [+ x# L' K  W- W& C& s2 T' a3 d' b/ i+ B. d6 f
      // Update Response Index and Count
. `' k: e7 q8 f( K  P8 g$ d% z      USB_ResponseIndexI++;
4 t, T* T# P" Y, |6 E1 t" |' c- `* u3 `      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {  J! i  R5 _; B$ f% m
        USB_ResponseIndexI = 0U;
- B# }8 T( f1 L4 X- v      }, L/ k+ {3 n- s7 [
      USB_ResponseCountI++;
, a. [# ~# r  g+ l; e6 J4 [5 m4 s- ?0 ^$ x3 U8 ~
      if (USB_ResponseIdle) {& [1 L6 P; U, J- S
        if (USB_ResponseCountI != USB_ResponseCountO) {$ P0 L  ^4 t+ A
          // Load data from response buffer to be sent back# F  p" _2 i: B7 l; @
          n = USB_ResponseIndexO++;+ i2 U4 W: ]1 t& m
          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {  C( h9 n* \( c9 e: Q" c0 e
            USB_ResponseIndexO = 0U;
* D1 b1 P6 ?7 X* N' e          }
) w0 w6 x( K- ~( \# {- B; L          USB_ResponseCountO++;
# b9 }4 l2 B* x  R% {/ n$ W6 S& W) O' j          USB_ResponseIdle = 0U;
! Y, g( P8 S2 r6 w. E6 A0 [          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);: v( l( \7 w, @- C, |
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
8 K) d% O3 _6 b6 ]& N, t                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
! m+ [& m( y) a9 x- O- K4 r& p                                        SetEPTxValid(ENDP1);3 ?$ O) r0 \# j. z
        }3 D5 e5 c: ?7 x5 C5 z# _
      }
+ N) v# x3 g' B1 |0 t& h    }* Q  a# f$ O" v9 ?& u+ x# x
        return 0;( F# L% |# |, O# P/ L
}
! v2 J2 ?0 a* R7 K- k1 \( w. H, `& n  a: [% a* \2 K% L
// SWO Data Queue Transfer
) z; P$ C! p1 H- W3 Q. L. V//   buf:    pointer to buffer with data# P" |# p  O* N$ q  E& y' y2 r
//   num:    number of bytes to transfer9 g2 \1 U5 f. y# u9 X
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
4 k+ x. f! l9 ]0 W' Y  l# |; K  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
: w, J% A4 \  G        uint32_t a;
: _! J( N, o+ ^) ]' x2 z! E        
+ K' a7 o7 C6 x7 }2 s        if(num>64)) L. P- M7 P" V
        {1 q) {- p) J! e0 X% l! \
                a=64;
  Y7 q" I7 H' D! e                TX_n=num-64;7 A! y; _% u6 J3 a9 R8 v
                pbuf=buf;
( _' K0 H, ~& v) I" b4 ?- R) d; g, R' F
        }else {
% G( I2 p, ~4 I* s& o9 W- }                a=num;1 r4 d4 {: U% |# O5 S6 P
                TX_n=0;
* j. \+ O: }0 V* v  U        }5 Y# N/ I; ^0 `# P% j1 [$ D
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
: E: F4 v9 x1 ?        SetEPTxCount(ENDP2,a);
" N) o  @. r- g( Q6 o        SetEPTxValid(ENDP2);, K: |+ @  O  f
}  ^$ u5 B+ e# m( i: Y  s# U/ `
& T+ f# l! n# {( V
// SWO Data Abort Transfer5 [/ v( i# i2 y$ u' O5 _- ]
void SWO_AbortTransfer (void) {4 U/ e0 `3 n1 X; a% v) i
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));* k) b6 ^1 I) q" s6 J3 Q
        //SetEPTxStatus(ENDP2, EP_TX_NAK);! r, r: ?; Y# P4 B, a. r& M( G, E
        SetEPTxStatus(ENDP2, EP_TX_DIS);+ C: J% Q, a; E9 C4 \& I1 q
        SetEPTxCount(ENDP2,0);
& G6 {- M! m7 S+ J1 c5 H+ X        //TX_n=0;
8 Y6 L+ [5 S1 l* }& y}
' v3 X3 ^$ h0 v5 C, ~/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/' }$ Q0 ^& R8 d# q5 z) L
! G1 {0 v$ r. U1 K3 C$ |
移植大概是这样的,利用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' l3 L+ E  g2 t3 z8 j. q# ZDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了8 G$ g4 _; J. H4 F( f( U+ J" _
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {- g* d7 l2 H, q( K+ b! v9 G: J
  return (DWT->CYCCNT);
, B6 C7 [( [4 N& g2 s}
5 x6 x0 W+ }  U: t4 C* J6 i* _1 z
* g8 w; C. ?' K# f% V, Z: uvoid DWT_Init(void)' Z% N  f  Y6 Z* X3 S( z, K
{
# i' c1 f  W: G; y    /* 使能DWT外设 */$ C2 ?$ g6 i1 n) V1 b0 j
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                & j/ ^8 q9 z0 n- j0 ^  Z0 w5 Z

1 H  F" b5 x% f! w    /* DWT CYCCNT寄存器计数清0 */4 y* S) Z  `+ P% `. G3 r3 W
    DWT->CYCCNT = (uint32_t)0u;# a) m$ w  K- A" Y* r7 U3 w

$ f0 l+ e) k! d/ e    /* 使能Cortex-M DWT CYCCNT寄存器 */; {  m8 a8 _0 H
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;, ~+ l$ `2 G: a" H. y; z
}; I% Y7 g  Q) p7 {3 Q2 \
        
# _6 U1 F6 i" O: a. \# M8 q$ @
5 j! E7 \4 W7 O1 j4 W9 @4 Z& h7 f然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
  L, Z+ E( h* W; N( b) f8 V- r1 s4 y9 z3 U
然后改为使用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不香么?& p, c; a0 {( b
声明这个变量static volatile uint32_t SWO_EventFlags=0;
; C' L# k, l& o, @, B! h在SWO里每一处调用osThreadFlagsSet的地方都改为如:0 a, S$ v+ c$ L( e& @% ], Z: s
//osThreadFlagsSet(SWO_ThreadId, 1U);3 m7 `: t9 A4 m
SWO_EventFlags = 1U;
7 x/ }: f: J9 [! U: A/ k- ~! @. ~2 N  p0 ^) O/ x

/ l% e% b+ Y  K! f// SWO Thread$ o  E( E' _1 [# Y! L
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
5 r* F1 t" _  ~* f8 Q% }  //uint32_t timeout;7 _8 r, z$ {# @
  uint32_t flags;
9 z+ z7 d- m: [, p) v  uint32_t count;3 `4 t# _% T$ J1 @0 j# O
  uint32_t index;) y' j' \0 v5 x, N! @  ~
  uint32_t i, n;
/ {  t- g) P2 f% j  //(void)   argument;8 Q4 J5 _# c8 {

% R  H2 a6 `' B1 [3 B/ C; L  //timeout = osWaitForever;  b" w6 c) e% J1 R
, p6 A3 y( T; ?6 J0 i( ~
  //for (;;) {* N* T/ h; I4 w- X
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);4 _  K0 d9 Y) i* B1 w
                if((SWO_EventFlags & 0x01)==0)return 0;
2 R3 L* M, a1 f- j3 \" e         * c& @' L* H& k4 s) q- X" V2 b; ]
                flags = SWO_EventFlags;
# U1 y* n$ |- `4 G3 }% x                SWO_EventFlags = 0U;
3 G2 s$ k  ?- F( ~    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {: x* }, h0 W/ s0 R$ q" Q2 P0 S
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子$ [8 ~# @* y: M
                        ;
. J! d' ?2 q" y9 J; K    } else {2 p; z$ C/ l7 M  G/ v! W$ R3 ?2 \
      //timeout = osWaitForever;$ W$ X% x+ i) G) R; c
      flags   = osFlagsErrorTimeout;. Q2 q7 [' }$ i1 I+ j
    }
! i. M+ C0 n7 s8 D5 o: a    if (TransferBusy == 0U) {
: L2 j7 q/ x  v      count = GetTraceCount();3 u0 j8 G# `8 x
      if (count != 0U) {% H( [7 ^6 R$ p, `
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);! [# ^& h% P/ ^6 M( T
        n = SWO_BUFFER_SIZE - index;' a1 I6 ^+ d" u: O( t) T. A
        if (count > n) {
) R6 e" F2 t6 _3 k          count = n;" `! u. N4 {( [% I  F2 ]
                                       
5 I( `9 d. h. |# ?% u( G4 ~8 t3 `/ X/ H        }
2 ]6 Y6 m1 F4 X' T* I9 V" ~                                if(count>USB_BLOCK_SIZE)
6 a- h/ q- d2 h+ c; m+ a) k                                        count=USB_BLOCK_SIZE;) a* Q& {4 S; w. t3 q) E
        if (flags != osFlagsErrorTimeout) {
$ C+ q8 v* Q& i          i = index & (USB_BLOCK_SIZE - 1U);
8 Z+ V; P& i$ S, [, e          if (i == 0U) {
5 Q$ T# t3 E9 x0 n, e            count &= ~(USB_BLOCK_SIZE - 1U);
( [( e9 J' z; v7 Q2 `7 d          } else {
  ^/ C) x6 S% T            n = USB_BLOCK_SIZE - i;9 B% S* q* c& z# A4 R" \
            if (count >= n) {
# E/ `4 H( |7 x2 V              count = n;
4 Y! n( T4 H7 M& [            } else {* j  K; {9 b( R( U: p
              count = 0U;
) o; M  O1 m$ }2 }% p/ B# h# a            }9 E& s/ w! b, \4 ]
          }
" _( u+ A# Z! i4 t- D        }
; A" }3 p8 E0 l/ N/ w5 Q        if (count != 0U) {
0 g4 f2 c9 h1 y: Z' A1 x' w7 v          TransferSize = count;5 k- F  X5 @1 b6 A. F7 O
          TransferBusy = 1U;
- I0 A( `; e. G6 ]          SWO_QueueTransfer(&TraceBuf[index], count);
9 f$ H+ d% Z' d6 F" W: G! V, Q; D! b        }; ]( _6 G7 J( b! z# v8 N8 C
      }
8 P  T- q* a+ ?. T    }2 L# `4 A) \- u: R+ `4 y2 S! s
  //}
5 K" S5 @( c2 O; a0 m                return 0;
. N; g7 n4 y. K5 \8 u- _}
9 Y& W3 u* v+ L" G5 T# B0 V利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.2 U# P) d+ h; i, Z$ n4 j
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
. j- ?, W1 d5 y8 f1 wstatic volatile uint32_t SWO_EventFlags=0;! b, D# ^) T+ S$ x+ h/ |
static volatile uint32_t timeout=osWaitForever;! D! l; _. x& P! X: l" L/ m/ `
static volatile uint32_t timeWait;
5 G0 g7 r/ r$ a函数改为这样
4 I- P' |; W; C3 l4 l3 ^/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
! E/ \' G* ~2 q) N- o3 f  //uint32_t timeout;5 V' x' c2 {5 `4 i
  uint32_t flags;0 h* o+ i' C* w* N$ c
  uint32_t count;
5 U2 \2 y5 ]+ h- R! V( C3 ~0 r7 a7 [  uint32_t index;# |& B9 S# X- v1 p1 g
  uint32_t i, n;0 _8 K) n/ g! i! N* u- A& u7 {
  //(void)   argument;# i  r& f2 s  c' c7 S) r# g4 ^
' Z. p5 v0 L9 _# g, U
  //timeout = osWaitForever;
: R% x( m! _. D% ^4 W) h' M! i# f# ?+ z5 d1 O2 v
  //for (;;) {
& ]9 ~* i8 B$ f; ]  C$ z    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
5 S+ Z. @  b  B4 W5 l9 Q: F* V                if((SWO_EventFlags & 0x01)==0)) \5 P  u: P* A
                {" w' S" M( t- \+ k) \
                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
3 q# ^* B% U( M5 J                        return 0;( o. Z5 |7 F- k5 x) w. A
                        
. E: ]! d3 h. ]. J( m# A                }% E- U( \4 ?/ ~- L3 I) g7 B
         ) l+ Y& C* ?# o  e5 J
                flags = SWO_EventFlags;
6 p" C; l6 K  V6 a1 X/ a                SWO_EventFlags = 0U;
1 y+ U6 m9 j4 r0 ]    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
. V2 T: Q* v0 V) h' \& A      timeout = SWO_STREAM_TIMEOUT;
8 M/ G0 L$ T+ m+ }: ~: ?      timeWait=DWT->CYCCNT;
, B* @4 m# [, W8 v; K1 ]    } else {
7 @, ~& s' N/ v1 _, ]      timeout = osWaitForever;; k. [, b! i" ~3 j# c  c1 m
      flags   = osFlagsErrorTimeout;' Q3 W2 p4 @7 @* ~2 J
    }5 \" H, q' d! G. W  `7 Q/ j
    if (TransferBusy == 0U) {+ j! G( v, q1 [# g/ x* b. V" v) x
      count = GetTraceCount();. u: T: T: _  P" _
      if (count != 0U) {
$ b% G; o" `! r/ v) W: U        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
; A$ ^( t% h( ]8 Z9 [* R- i        n = SWO_BUFFER_SIZE - index;
* D1 B5 }2 B  p$ s1 p3 a        if (count > n) {
: T) M9 y! y) D0 v. Q, L! y          count = n;
0 \/ A- Q) a3 Z                                       
. D. m( z  @+ Z, S5 R        }" K( W0 O/ ~7 r- p, J6 M3 {4 ^7 t* }
                                if(count>USB_BLOCK_SIZE)4 j1 V7 W# T2 ?/ b0 G
                                        count=USB_BLOCK_SIZE;
! H9 I! ^+ m: a' W        if (flags != osFlagsErrorTimeout) {8 c  E- H5 s  {" p' M
          i = index & (USB_BLOCK_SIZE - 1U);
* t5 i& o* q- X' ^          if (i == 0U) {
+ d& i9 i* X. h) `3 _            count &= ~(USB_BLOCK_SIZE - 1U);
! j, i( l# O# G6 h+ n% f* `4 R1 |* S          } else {" L3 q" n8 c/ L  g! o* A3 n
            n = USB_BLOCK_SIZE - i;" E: B5 Y8 Y0 c* `- F& R
            if (count >= n) {% Q- E1 }" ]" i. E
              count = n;& u3 w" B3 m0 z
            } else {: \8 W4 r& q0 F  c
              count = 0U;
5 Y% k8 |# A, ^9 u4 H$ M            }
; ^% i. c' F& ?4 q$ A+ T          }* `3 t, r/ m# L
        }
6 n& a! x& e2 k4 k4 A  n$ J' N        if (count != 0U) {# h, G! w. v' _- X
          TransferSize = count;
% l, x7 v9 l8 p9 H2 c0 l5 _          TransferBusy = 1U;
& B$ b3 N; q9 K. X# D          SWO_QueueTransfer(&TraceBuf[index], count);
3 p5 C" h4 ^: Z; z0 c  A+ V        }
1 Q& ^1 O8 l6 p& a+ X; u+ L      }
: a' T$ \0 ?# C, W9 c    }& O- s/ L1 P  M
  //}
# ^0 i/ p1 z- {9 P* }6 C! P                return 0;, l' P7 E3 D( ?1 u
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了# a- H- v3 h% u: B. z

% N: _5 j" R4 Y% Y0 E; l" rCDC部分暂时还没加入,SWD现在是非常稳定的,而且速度感觉也是不差,就是SWO的问题不知道如何弄,另外看到其它人弄DAP,把SWD读写部分改为SPI,看了一些SWD读写协议,它好像有一个8位一组和32位一组的部分,如果换为SPI是不是就可以更快的速度读写了,另外DAP与USB之间的FIFO部分它有一个队列等待,看意思就是当有标志着队列的包时,就等待接收更多的包缓存后再执行处理,对于批量端点,连续的传输大量数据确实是批量端点的长处,因为批量数据时,端点接收完一包后不会NAK,端点会接着接收下一包,少了一些中间商的处理,也尝试过这个队列等待修改为不等待,即接收一个包,执行一次DAP处理,它同样是能正常运行的,对于批量传输来来说,感觉应该队列等待会提高USB传输的速度,比如下载程序时,Keil 一次性下发多个命令包,比如达到1K或者2K字节或者更多,DAP先全部利用批量端点的优势一次性接收下来缓存,然后DAP才执行一个个命令包的响应处理,对于读写部分构成字节为一组的就使用SPI读写数据,零散的位部分像ACK,SWD复位等待部分用IO模拟来处理,SWO部分感觉如果能修改为SPI接收估计时钟频率可以更高,这样响应速度更快,另外STM32_USB-FS-Device_Lib_V4.1.0固件库的USB端点没有FIFO,不像OTG USB FS 库哪样端点都带有FIFO,但是提供双缓存端点,准备把端点修改为双缓存的,这样当连续多包传输时,端点就不会NAK,少了这个等待时间,能增加端点的传输速率/ D4 z4 P4 t) u
4 n- ]8 C! t7 _5 Q/ B% V
% a# y& Z- M+ Z5 A3 V
int main(void)8 _3 }. h$ a( v& y
{
! T* \5 e2 B! A* ~8 y7 I  DWT_Init();
7 S5 n) l  P9 n. ]  L5 {8 W        DAP_Setup();
4 H! i% S) h' L2 s" e- K4 B  USB_Interrupts_Config();
' Z, j8 c6 Z. F6 t5 R! u1 k  Set_USBClock();  ]$ }) m% a+ w0 @$ U6 a2 @
  USB_Init();& E) T2 W: n" L/ m6 E
        //TIM3_Init(35999,0);% ]. U& w% }# c& X/ b
        //TIM_Cmd(TIM3,ENABLE);
; A: Q8 V7 J3 }4 \        5 m4 F/ s; @! E) M* R
        
- R9 U: N3 {) X- `! s: X  while (1)( V2 G# ?* H( i7 s
  {
) i5 X# C& u# A( j                DAP_Thread();
2 B$ f9 f# j* W. m& T                #if (SWO_STREAM != 0)
" m- Y- L$ a/ _( e1 P$ a7 @/ d                SWO_Thread();
$ [* d, e7 x  N+ F                #endif5 p1 e) Q8 G+ N1 g0 l
  }( E# D: W+ t9 t- L1 L3 l! z
}
3 `3 k, d$ v& K; G/ ~0 L& |7 @( ~$ ?( \  I
对于DAP_config.h的IO配置我是这样弄的. H) ?+ j; n2 l3 m: K7 T$ S# P
///@}2 s, m$ a* K2 E4 i- m& q- S
// Debug Port I/O Pins
& n) y0 j* M7 H  U$ L
/ ~) r. }0 u' D( x, j0 h// SWCLK/TCK Pin                GPIOA[6]" }$ y% c3 M% b3 k: w! a& ~
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
+ z/ A4 N4 G* g#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
, V& ^% V' h, k1 |" a! g5 L0 m; a6 b( ?: T' k
// SWDIO/TMS Pin                GPIOA[7]0 p4 ^( o: h7 }$ b" S! @( a. I6 |
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
! ~5 _, ?3 {! k3 u( `: j#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C# r9 Q: Q/ M( ]( {5 K8 T% w9 c

& r$ B% b! Q5 I// SWDIO Output Enable Pin      GPIOA[7]& i! ^+ J: p: O
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \3 [2 _! [) g! c; s2 k( V* a
                                                                                                                                *(uint32_t*)0x42210070 = 1; \
; [! o2 K0 V# s7 p                                                                                                                                *(uint32_t*)0x42210074 = 1; \- g: Y5 A) w: J
                                                                                                                                *(uint32_t*)0x42210078 = 0; \+ J6 D! ^  U- ]( [4 i6 c9 E4 \
                                                                                                                                *(uint32_t*)0x4221007C = 0;}  p+ X1 z/ T9 I% f8 f

) R# W/ W9 t# s#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \; O7 x  K9 y) ]: H9 f
                                                                                                                                *(uint32_t*)0x42210070 = 0; \' i5 B7 _* u9 O4 P2 B9 x  V3 U  a
                                                                                                                                *(uint32_t*)0x42210074 = 0; \) ^0 p; u/ [8 Q# m4 `
                                                                                                                                *(uint32_t*)0x42210078 = 0; \
, k  t0 D* Z3 I( b5 L2 W: J                                                                                                                                *(uint32_t*)0x4221007C = 1; }& s* \7 q3 p- r  [, @; w

9 e( y. p% t- u# t// TDI Pin                      GPIOA[8]) X) N  t! z- B
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0& u( k. Z5 O. y% P
#define TDI_IN                                     *(volatile uint32_t*)0x422101204 F" j3 s- Q3 m$ R1 I9 W
' r! H( e7 d1 a+ B( L7 n. d
// TDO Pin                      GPIOA[10]1 ]+ @2 ]6 g# F7 i1 [
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8  S1 N* \9 K1 G- X5 a- A: d
#define TDO_IN                                     *(volatile uint32_t*)0x422101283 f9 C$ b/ G  L; ?  ?4 A
. s2 c$ ?# Z9 C+ K( I+ W8 H
// nTRST Pin                    GPIOB[3]
, @* V% B) {2 \* S#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
9 H  d2 e+ w# E0 `" M#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C
. L" L# T6 q3 ~/ g; @) q. X1 j5 j" M& E& [8 k- e
// nRESET Pin                   GPIOB[4]
! t* F8 K" J* V1 _4 k#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
! p# E. `7 Q& ?#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
4 Z: s9 H. c, ], v7 N( R
8 p( I# B& {0 j# L, o// nRESET Output Enable Pin     GPIOB[4]
. y% B9 C1 ]9 B% I9 i5 z6 Y7 C: \' D#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
  W4 f6 K; P, n, g                                                                                                                                *(uint32_t*)0x42218040 = 1; \  Z% N0 K7 G6 g0 {7 ^4 I* l
                                                                                                                                *(uint32_t*)0x42218044 = 1; \
% l6 W( s7 y0 l8 _% I6 d                                                                                                                                *(uint32_t*)0x42218048 = 0; \- v- z9 K% h! J$ K8 u) ^
                                                                                                                                *(uint32_t*)0x4221804C = 0; } & G% V, U3 s7 b4 f

4 e# H9 N- Z  I& \! Q. I#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
. G: v/ j+ q3 M                                                                                                                                *(uint32_t*)0x42218040 = 0; \) ?$ v7 _0 P, O3 E
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
2 W/ Z" F( k/ L1 Z: Q                                                                                                                                *(uint32_t*)0x42218048 = 0;\
( B6 j( |2 g  Y2 O                                                                                                                                *(uint32_t*)0x4221804C = 1; }
' W0 k( f7 b4 l4 w7 y. w$ l$ B$ n+ r' k4 T+ Y
$ m$ W9 w& x9 U. m; N8 r" n
// Debug Unit LEDs8 t) |0 O2 g' W

. q( {' T; j' `; t// Connected LED                GPIOC[13]
" |2 x& G$ A/ ]7 T; w% b8 u' T#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
( ?; G8 g; c' |; B/ @% @6 q0 j7 G#define LED_IN                                                       *(volatile uint32_t*)0x42220134
6 N; T* f, P. M: U- H0 q0 C/ Q2 i1 A
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
# n& u% |3 ?" H& ?7 _                                                                                                                                *(uint32_t*)0x422200D0 = 0; \. u0 M& n. e7 {: U
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \0 u% c/ _$ M4 _$ _4 c
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \8 m% T" J! g  X$ F* j8 t
                                                                                                                                *(uint32_t*)0x422200DC = 1; }" o! f! J& `  l, o6 W6 h! y( ~
// Target Running LED           Not available7 c6 \4 m+ B! p

# _" E6 E8 d# y7 @( P/ n& b) v& Z// SWCLK/TCK I/O pin -------------------------------------
4 L: j* {- f; }: s8 p1 k( u
( Z- N+ |; ^* k8 |- u/** SWCLK/TCK I/O pin: Get Input.* M) m- D" T, f. G* Q" z1 k
\return Current status of the SWCLK/TCK DAP hardware I/O pin.5 J1 f+ L% a( u* l" |
*// U5 N* h# v, |
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
* O- x! R6 W* e/ J  return (SWCLK_TCK_IN);
- k9 B/ y4 o2 f) y2 `; q}; U9 \" [* V3 T
4 E6 C2 U4 d- \4 S
/** SWCLK/TCK I/O pin: Set Output to High.! M) e: K2 A0 |' C
Set the SWCLK/TCK DAP hardware I/O pin to high level.
" U: z/ U2 N2 j0 |5 b1 v*/
4 S1 c8 ]2 _; y2 Z__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {6 T. w' N, x/ p2 ]! \
  SWCLK_TCK_OUT = 1;
: A. K1 S# I, \4 a" g& L( D. y}, T5 W" `& P# r* ]/ V* w0 C! b) h
% ?# X4 G( j$ A! Z% D
/** SWCLK/TCK I/O pin: Set Output to Low.
5 ]2 O+ f/ I( w# `' Q: [- eSet the SWCLK/TCK DAP hardware I/O pin to low level.0 o' D, _& L8 l0 m9 O8 n' P
*/
4 m" d5 c8 j8 |  d3 D4 ~__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
3 ~" }0 I7 G4 u2 u  ^9 x  SWCLK_TCK_OUT = 0;6 r% k& p" G  g
}
4 j/ m6 x6 I. B6 R! [8 \* R) z# g, p$ z0 R( [6 W
4 B, s) ^5 O% ]2 i5 j
// SWDIO/TMS Pin I/O --------------------------------------4 U% E4 X3 a: n' R& O3 A
" {. q6 ~6 K" H3 C3 K% X
/** SWDIO/TMS I/O pin: Get Input.( w1 B4 Y1 Z8 c; s7 Q
\return Current status of the SWDIO/TMS DAP hardware I/O pin.( M! F9 T2 C; w9 Y
*/
  z4 R* X9 z) |4 d2 \8 K; c__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
" S' j7 H: E0 `) R/ s/ g& ^  return (SWDIO_TMS_IN);$ ?1 S0 N0 E% ^+ H5 v
}* P: ^; w+ u5 }( e2 `

- V$ V2 F$ D' h6 `( B/** SWDIO/TMS I/O pin: Set Output to High.
* t$ N. Z% A) WSet the SWDIO/TMS DAP hardware I/O pin to high level., r0 U* x8 \) g9 j3 L
*/$ u7 B+ E( ]; H6 B3 s& l
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {
; O' G/ d+ ~9 Z$ |  SWDIO_TMS_OUT = 1;/ ^9 q2 s# p5 g& c. P9 n" ?& T
}
$ }3 ^; z: a. r9 d7 P
5 i  B, `% ^: Z0 l/ k" N+ ^% n/** SWDIO/TMS I/O pin: Set Output to Low." x: {- x9 Y/ x9 J7 w1 o
Set the SWDIO/TMS DAP hardware I/O pin to low level.$ N& Y+ N: A% N+ H6 ~$ X3 K7 E: D
*/
" E+ r. ?: Z  R. L__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {8 j+ A: A9 z+ v( A) x
  SWDIO_TMS_OUT = 0;* e* ~! @4 P  ?, G
}7 x; v' r# k- Q. M9 r( D- L- o) ?* s: y

- v' x0 D7 G8 [- [4 d6 E/** SWDIO I/O pin: Get Input (used in SWD mode only).
0 F  a5 P$ l7 J* D( O3 P( T\return Current status of the SWDIO DAP hardware I/O pin.
1 S% }) [& D8 ]; {*/
5 s1 r" Q* [1 T0 k$ N$ ?__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
$ K3 s; y% d' C' C4 v8 w- Y  return (SWDIO_TMS_IN);) H* O' \! W% \9 y* z' E
}. P# f+ A1 I, ]- k0 T
' }) j5 P3 p. k6 p, M# \
/** SWDIO I/O pin: Set Output (used in SWD mode only).+ p7 O5 X3 S2 }& D
\param bit Output value for the SWDIO DAP hardware I/O pin./ [; t/ O) D% O9 X
*/
( ]) e) U( A! p4 V9 m$ g__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
- ?0 Q0 J1 e' g  SWDIO_TMS_OUT = bit;' q8 t( U* l6 {; c0 E+ B0 l: i
}5 U- M' z6 t' g% w
3 `- L( k2 ^. i* l8 o! W
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).3 H, o0 O5 q9 e  o; m, Q
Configure the SWDIO DAP hardware I/O pin to output mode. This function is) Q: y8 r* T  U2 G/ Y
called prior \ref PIN_SWDIO_OUT function calls.6 G1 c) c/ M- Q0 `# x
*/
9 x. I+ l. ]5 Y* _) Q: k__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
1 B# B$ m3 U, l: P0 H, b& k% @5 M  SWDIO_Output();& A+ k+ _( S7 A8 y7 l
}
- D3 O7 a8 t/ J. s1 ?$ r; y0 F: g$ V' u: _. n& A2 j+ W* Z
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
$ N+ F. {2 ?- J& F$ f4 q4 iConfigure the SWDIO DAP hardware I/O pin to input mode. This function is
# @9 T7 [7 R# D9 l& `+ Ocalled prior \ref PIN_SWDIO_IN function calls.9 x) B# g, k+ s# H
*/
5 u% F& S' d2 o0 r' H__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {: Y0 _; k9 v+ U9 E
  SWDIO_Input();  _8 q1 v( i, g
}
5 T; D! k- Q# \. ?) |
0 O* V9 s. G# \$ V8 H: Z+ ]楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
' H5 ^- V3 Z4 F4 v即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
  F( c% I: F9 O* T# A2 ], W
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

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