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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。. l  j$ ]' w9 d+ v+ }
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:503 w7 @) d. L$ j2 ?$ Z* v
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

8 J' j6 o' d+ ]( t$ n我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。! E: N5 N! m" v
0 L" w+ U2 O  T% n
软件复位是另外一种情况,需要向目标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
' z6 E6 M- ^/ L/ e5 X可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

) U, i' K5 ?/ `( A. k. knRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
7 u5 K& K0 n" K/ p7 I. _7 I你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。
6 K* r) u( K6 S9 R; M3 @. w+ s0 r
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 ; d4 a/ E+ g  o# ~  K; N6 F. e1 |
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。% {1 R" q9 t% V* A- X7 E
2 W1 V  K% ?$ o; Z' h2 A2 h# ^
! o+ J( k( n! G. C% M6 F
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?: M4 e* u  x2 Q. s: Y$ V9 O& K
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
) X2 @3 a- W  _5 \4 @+ n
起点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系统,轮询执行6 Z  L& u" y6 }0 q9 j! O2 |
/**
1 T5 s+ p- F" N$ k9 D5 M6 _$ P  ******************************************************************************
$ X- u$ z7 t. k  * @file    usb_endp.c
. e/ \" N& A9 p2 i  * @author  MCD Application Team
7 {  e: E  d2 G8 g- G  * @version V4.1.0/ S( _: m" i( v5 U' V
  * @date    26-May-20179 P# u' ?, a/ f
  * @brief   Endpoint routines
$ A4 }: @' ^0 Y! C  ******************************************************************************
/ n  ^# m. m+ @% U9 {/ _7 S6 }  * @attention1 s6 e" ~, P2 T$ }$ W2 N
  *
2 C  u3 c; N7 f! b7 F9 O  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
5 {# ^) G0 J  c$ @- P9 x  *
) L: ]: R! A1 `- E; ~* m# h  * Redistribution and use in source and binary forms, with or without modification,1 x( m9 m% E3 ~8 {
  * are permitted provided that the following conditions are met:
& w' ]* @# P5 S+ s  *   1. Redistributions of source code must retain the above copyright notice,
% {7 }$ ?! m, D1 H+ B8 y3 a# Y  *      this list of conditions and the following disclaimer.
0 q# l) K! V/ s! G5 ~( ^; w  *   2. Redistributions in binary form must reproduce the above copyright notice,: C5 x7 ~& n& A2 p* F% \9 O
  *      this list of conditions and the following disclaimer in the documentation
* n, G# f+ R1 \  x9 C+ d  ]  *      and/or other materials provided with the distribution.2 ~8 }( ~" B/ s1 j+ B7 ~; V5 G2 B
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
: j' V) b. s, w4 }- }4 A  *      may be used to endorse or promote products derived from this software) M6 L" B" r# ~& T" E8 T! R
  *      without specific prior written permission.$ R2 p3 E2 _$ P- k/ Z5 ?0 \( U
  *
0 d. o0 O' G9 M5 P  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"5 n* _) `5 L  h1 k
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE' @: g9 A( x; F1 `' b9 ]
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE1 S) O1 j5 [* y6 H1 Z+ r8 S
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
: ]5 w  c& J% H  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL) n4 S/ h  L& e
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR9 q5 W! B9 F( \
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER7 T" i7 Y5 s  d
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* i1 C( f9 w5 w" G$ Q8 o
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
. O. }% D/ ~! P" U3 V  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
, |4 p" A, P) }: D" z8 ?  *3 w4 T( U  \* A' V
  ******************************************************************************
: d, X) w" I. H3 x! E" k2 r" x  */4 r' L6 |7 W# s7 ], e0 z
+ N& I; l( ?5 ?! \: W- m
5 Z9 P+ q* o5 U5 W
/* Includes ------------------------------------------------------------------*/
; ^7 z# I  d  b6 ]# C#include "hw_config.h"
( c5 \- e8 C# J- H; R7 Q# [#include "usb_lib.h"5 k' z& }' x- t! C. W8 i
#include "usb_istr.h"
/ r0 X! Y: Z9 N4 e#include "stepper.h"
- {8 O/ o7 d. K2 g% W+ |#include "string.h"& `6 [5 F' S6 O! c. O1 A4 U9 H  {

! Y" ~- z7 S7 b# I& h, ~+ n#include "DAP_config.h"$ k' F. I% F" C
#include "DAP.h"
8 A6 l3 C0 h6 P4 B8 \
2 O7 R& q5 j8 ?  l8 v
. x  G; u" \4 B. z$ _0 O/* Private typedef -----------------------------------------------------------*/
$ X6 s# m3 p! \: o' F# x4 H- s/* Private define ------------------------------------------------------------*/
" q" m$ @. ^: T* M/* Private macro -------------------------------------------------------------*/
6 i6 p) o, x7 f! g  @/* Private variables ---------------------------------------------------------*/
8 _) t3 }* T2 S" C( s& qstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In9 }& v. m8 h. m
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
- _; y' P' f6 Z( a0 q1 K- w4 y' tstatic volatile uint16_t USB_RequestCountI;     // Request  Count In
' P4 v( k* H% o% p& e& r) e3 ustatic volatile uint16_t USB_RequestCountO;     // Request  Count Out8 R% E6 k% B7 y( a3 J7 E# k
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag8 F$ \/ m) E9 l5 w5 m
: M- o4 z' ?2 U* }  d, q
static volatile uint16_t USB_ResponseIndexI;    // Response Index In
& s( e4 W4 q# ?- Rstatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out
! u: u- l% e3 d) Xstatic volatile uint16_t USB_ResponseCountI;    // Response Count In+ M( O3 H% u9 f& A! c, M; m
static volatile uint16_t USB_ResponseCountO;    // Response Count Out! M0 M8 P  G) R7 f/ g+ ^$ w- p
static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
6 m% n* w; d' B1 U0 T: dstatic volatile uint32_t USB_EventFlags;/ v8 f0 X; q" k4 j8 z

2 I7 V0 t. o6 w$ fstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
0 y+ G4 ^0 `, k; s) gstatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer$ B2 m, {7 G) q, b7 ^1 L
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
: i4 J0 M3 T. P: S. ^0 h+ H- G3 Z+ V- T- T6 e8 q7 a& _
/* Private function prototypes -----------------------------------------------*/6 j( o/ f( ]5 D- f) k
/* Private functions ---------------------------------------------------------*/
& {9 o( v+ ?) @  g! ~7 P* h/*******************************************************************************2 n* X6 N) u+ h  K8 M' N
* Function Name  : EP1_OUT_Callback.
8 \5 i7 [4 m+ Z+ o. Y( S1 z1 ~' B* Description    : EP1 OUT Callback Routine.# C0 J# Q$ x! Z" I
* Input          : None.
: G( M: g& K3 {/ f6 x* Output         : None.& z; q3 C; a; s3 z
* Return         : None.
% E" _* X# s- I, Y  t' w* E*******************************************************************************/
8 [2 W6 o! x, |& v" W& h; svoid EP1_OUT_Callback(void)5 ?* M. s+ Q4 n' u* X
{4 V5 ?! ^  p( L
        uint16_t n;
. c( z) _" l0 [" w
3 s' ?0 r* p6 R  o; }6 S! b0 Z        n = GetEPRxCount(ENDP1);  y* A+ b6 e9 d) g# A
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);5 V( A8 o# J+ f1 w4 I+ t+ p8 C  S
        if(n !=0){: i$ o, i# o' Y# Y/ n! g
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {6 o1 M6 H/ g* s  `, M" p) l- h: X# ?
                        DAP_TransferAbort = 1U;4 _7 k! @2 Y9 \+ b- ~) L
                } else {
  S) J3 @6 K5 g                        USB_RequestIndexI++;) Q- I) K( v% Y* q% @
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
$ `* [* Y# E. M2 @                                USB_RequestIndexI = 0U;* a" P/ F4 c7 l  ]; u
      }
  Q; s% ~( d1 f. s1 e- E      USB_RequestCountI++;
2 U9 f% e  [9 c' ]        USB_EventFlags = 0x01;
$ J  d' C$ ^8 P# F; H    }
" c( u7 s, N) t7 L        }        
/ c) F* z8 y: p/ z; L        // Start reception of next request packet
$ h1 g6 m# b8 f; Y% C8 T9 ?        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
  k& t+ A& S! t! u8 n                SetEPRxStatus(ENDP1, EP_RX_VALID);
, _  z  `% b5 r1 C        } else {% B! X. Y" j6 O/ S/ v; Z5 t
                USB_RequestIdle = 1U;
& e) J1 D( I- F' ~: B        }                        * [: z  t) E  c+ n8 f/ x
}0 `' {4 x9 u9 X) A1 M- o

/ i/ c9 o$ l6 e/*******************************************************************************
) }9 x' v2 ?' E( f* Function Name  : EP2_OUT_Callback.
5 ^+ `3 J: g! [" t* Description    : EP2 OUT Callback Routine.: U' L  F+ U9 X' l) R. M
* Input          : None.- O; e- @! j: _. {, A
* Output         : None.5 Y3 E1 T! k* c8 J% m
* Return         : None.
0 P7 n/ }. l/ T" S/ L*******************************************************************************/
  }1 B; F9 c; _+ E" l1 R" t3 @+ f% z- h2 sstatic volatile uint32_t TX_n;4 q8 x. {; d, S6 }) Y# E
static uint8_t *pbuf;
4 d* a/ J% r+ S& `void EP2_IN_Callback(void). |$ D  ^: f: v% [6 @' Y
{7 g. p% Z. T0 [; U' X: [
        uint32_t a;
' F0 A- {. x! {4 d0 L        if(TX_n>0){: @" C3 k  f9 u' c* Y2 H9 _3 U+ ^
                pbuf+=64;
$ O2 j( d1 h& ^3 B) k                if(TX_n>64){* [+ A# ?, `% u8 W8 c" G
                        a=64;/ m  u# ~$ _! I7 W0 s, Y
                        TX_n-=64;# L9 E+ {  j& ]1 z( J
                        & s4 N7 T" t) F
                }else{
+ r6 B3 D; d5 O$ {, G                        a=TX_n;. D0 Z. L* _/ H' ?& q. g5 _
                        TX_n=0;
0 w# A" {  S) P' [                }; Q0 V' q' t2 A# o' e& f4 f1 a
                9 Z3 c5 ^' R# o2 t3 X% X
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);5 _+ |8 h: X3 G* W+ b/ z
        SetEPTxCount(ENDP2,a);
$ \6 a, {9 R4 n& ]' d8 v                7 |& D& [) G4 z$ w/ V7 F$ M' c
        SetEPTxValid(ENDP2);
# H2 h0 Q3 x2 K. A9 u        }else{: ^1 h) x8 j& b- {
                #if (SWO_STREAM != 0)! N- a$ w# i2 A' O! k. \
                SWO_TransferComplete();/ D0 d. D8 B6 w  R% s
                #endif
2 }! l8 ~+ c' b9 v1 t" x( i        }$ P2 N, N  ^6 t0 P( y2 z
}
5 ?0 ^7 J& o* v8 a, o. l* X4 o- d' ?
7 ?$ k1 [/ v4 x/*******************************************************************************
+ U# a6 T- X# w) a# l, q* Function Name  : EP1_IN_Callback.9 Q8 ]) K/ \& d
* Description    : EP1 IN Callback Routine." l" y# T/ r  w& t5 ~; m6 U
* Input          : None.
; D* q, e0 q' }* Output         : None.
! X" y( n, G$ g* Return         : None.# l% \, `2 t8 W0 W1 v
*******************************************************************************/
% P- u: `; t9 {" s( s0 {void EP1_IN_Callback(void)
* t6 {1 W/ x1 z# t{
# y) @) M/ p" d3 \3 A* A    if (USB_ResponseCountI != USB_ResponseCountO) {( t- ^2 p5 |7 l+ j0 K+ k0 m: X
      // Load data from response buffer to be sent back; t1 E: c& u3 w  R& m
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
6 H. G. L5 g( u& [" c" d8 @+ U                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
: s9 A' b; |8 O8 O                        SetEPTxValid(ENDP1);                        
6 Y7 P/ g( V9 P# g- M4 [      USB_ResponseIndexO++;; t6 R: D" @7 g
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
; g: O$ R# I. U2 l. D        USB_ResponseIndexO = 0U;
& S# W: w/ `' V; `7 J* l+ Q      }# S9 S4 M$ {; S8 w' ]. e
      USB_ResponseCountO++;
1 g4 p1 e2 P# d( W    } else {6 }0 _/ |; [% t% n1 a, [: ^
      USB_ResponseIdle = 1U;- O; z! J* t+ h4 b
    }  
2 d$ `" Y8 ~$ z/ m}/ k/ h1 t* l* x8 n$ j
6 }2 @/ C# Z  n7 j: y$ o2 W
// Called during USBD_Initialize to initialize the USB HID class instance.
- e$ @' z9 _  @* Y* _* h! W4 X. e/ nvoid DAP_FIFO_Init(void)
( }) h) [. W& x& n) o, P, k{
4 x. _  o2 ^2 l" x8 `3 j% W; y7 ^    // Initialize variables
( h' w& v7 A% R' n0 `    USB_RequestIndexI  = 0U;- _4 q7 X8 l7 s( e# x5 T
    USB_RequestIndexO  = 0U;& y' o7 |& \) I: ]- I
    USB_RequestCountI  = 0U;
" I. e2 f+ g! M/ W, I8 j8 h    USB_RequestCountO  = 0U;9 \. `/ a! J# I, h5 w
    USB_ResponseIndexI = 0U;# D' C8 z% c' v1 Z) l
    USB_ResponseIndexO = 0U;, V4 Q4 }% _6 u, _8 y- V
    USB_ResponseCountI = 0U;9 {' S* B/ H6 T. W+ ^, t! l
    USB_ResponseCountO = 0U;
' S3 J, `( X1 _. b6 d" W7 e    USB_ResponseIdle   = 1U;
( K$ M6 U3 |. m    USB_EventFlags     = 0U;
+ u& c+ C* Y, ^' Y' N- O}) y6 n) @9 ^8 `1 ^4 U* B
# k9 V) X% c; X, J+ @
uint8_t DAP_Thread (void) {/ B! j9 B( {. ?; T
  uint32_t flags;6 }- O4 P& b/ ]. d  g7 ?
  uint32_t n;
8 q  g! B- W' N# {8 b! u  D& y( ^
  //for (;;) {. f! c9 u$ m9 U- @3 R7 @, M
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
/ |9 E1 B5 ]! U. V                if((USB_EventFlags & 0x81) == 0)
7 d9 _4 x# b6 Y" g* [5 F" r                {0 }1 A& f& N  A( h( _- w' F8 e. q. h
                        return 0;
/ Y5 a4 ^' l& c: \) c                }
  E0 \) y7 K8 h9 p. }  [                USB_EventFlags &= (~0X81);. a8 A+ s" `; U& g
                $ n: X! v5 N1 X: I
                                       
7 s9 k6 a: b3 n    // Process pending requests1 s' K' o& O! Z/ V8 B6 t8 }
    while (USB_RequestCountI != USB_RequestCountO) {
* J/ }- V" o* H% _5 @% E3 Q                //if (USB_RequestCountI != USB_RequestCountO) {
' y. `/ S& s( [3 i, D      // Handle Queue Commands& V& F9 D% `" J! Y7 A6 O! G, Z
      n = USB_RequestIndexO;7 b/ t9 g3 l3 `
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
6 E# Y9 Z) y- ~, o7 A5 t( V4 H8 ?" J                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {; p4 G' i# I& |9 C
        USB_Request[n][0] = ID_DAP_ExecuteCommands;. r5 d* }3 V* Z1 B3 d' Y8 w
        n++;5 S, D: [! {1 M5 o- [  W
        if (n == DAP_PACKET_COUNT) {
% [4 _" K) W3 U$ f: `( [          n = 0U;
* s9 x9 Z+ Z0 E" z+ F6 ]        }
8 ?$ r6 k! E' h9 O; D: F3 M- ?& L        if (n == USB_RequestIndexI) {
; \7 d# @1 P" r* C          flags = USB_EventFlags;
# o+ ^# r1 h" n" ]          if (flags & 0x80U) {
1 M* e' O/ S. s% e" u- v9 P            break;; G# ~1 b, Y  M; K% ]- e+ E% x2 n$ w
          }8 \! p; O+ D5 ^7 @' [- M
        }
% Z% F. k  T3 E2 x1 R3 L, A      }
- @! t1 W+ ^" z. X' B9 _8 k5 l: E
      // Execute DAP Command (process request and prepare response)
9 y( o! P4 w( m' h: r  _! s      USB_RespSize[USB_ResponseIndexI] =
" i9 ]3 a0 |9 V( ]- T; q0 I        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);8 e! H) M) }# r! ^6 G/ n

1 ?2 I, v: z' {: e0 u; m      // Update Request Index and Count
$ N- B1 b$ A+ C8 d5 p      USB_RequestIndexO++;$ n- d3 H+ M5 U
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
8 c  t, V3 X9 ~! [        USB_RequestIndexO = 0U;
* U( P5 o3 L* k! H2 i      }
0 x4 M5 G; ^. q  E- i5 ^      USB_RequestCountO++;
, m. h& Y, r$ w/ K3 U$ K. @% \% J; y. r8 s
      if (USB_RequestIdle) {" A. Z5 \% J4 S! X  N: o0 y  {
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {' H, B$ ?% l- o8 ?; v  H  |
          USB_RequestIdle = 0U;
# G. k8 H3 V! u          SetEPRxStatus(ENDP1, EP_RX_VALID);8 F, N" x' x5 z% k: f/ ~1 t' D5 u
        }) B4 L- F( B+ |. i) R, P6 F7 b
      }
% r* i  i6 ^; ?' G; c0 w8 B- e7 p& D7 N: @# I$ b3 D: Z
      // Update Response Index and Count/ D+ D6 W- w5 ?8 G' K
      USB_ResponseIndexI++;
4 h) ]- ]& v( r, ?: p6 U$ H6 C  M      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {% g) j: D- b1 B3 r6 _( U1 e3 T  a
        USB_ResponseIndexI = 0U;
5 S4 C4 q  L7 m/ {      }. q* F% ^8 X: P9 w, g' T+ H
      USB_ResponseCountI++;9 M! b% y/ z! x1 Q% \# q4 _

- j* ^6 ^8 c! n( v5 P' d      if (USB_ResponseIdle) {1 \+ Z0 q! w; e+ B) X
        if (USB_ResponseCountI != USB_ResponseCountO) {
& V& G& Z3 X5 ^5 y          // Load data from response buffer to be sent back& Y5 Z* D2 z6 l- a; ?
          n = USB_ResponseIndexO++;
) c& j( x3 T( B5 h* [: ]          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {# d! [  _2 M0 R) {! s$ I5 K0 M
            USB_ResponseIndexO = 0U;/ e: ^5 G. l/ J; }3 ^$ |* s/ ~$ h
          }* x, b& k! F! E0 p% ]  |
          USB_ResponseCountO++;
# \/ G4 M8 Q9 z! |* d* }          USB_ResponseIdle = 0U;. W& x" P1 ~6 U4 C% ?3 f5 \' J
          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);! u: Q- z/ I, ]8 Y+ h' n7 V" b1 V
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
; i3 C+ K& i! u5 e, z                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
* u9 r6 [% Q; X0 e  i                                        SetEPTxValid(ENDP1);+ V) l8 o# ^9 p4 K% z+ P% d9 D
        }5 H9 V6 c1 `, Q- D3 j2 q
      }, k" W: G1 s9 g; U; J# s
    }: @2 r* b; f- d2 R+ S7 L
        return 0;7 R! K+ g1 W6 D
}
; W) O* @, a& U* _9 v' d; D! Z
4 F$ V" z8 f0 e1 B, F+ l! X// SWO Data Queue Transfer. f* _$ B" \& R- F) v
//   buf:    pointer to buffer with data, y3 j3 E: C3 E: I: d8 ^0 O( S
//   num:    number of bytes to transfer
; R+ {' \+ Y/ x* Lvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {. H, y; \* |' [9 J: o; O9 u9 K/ E0 W
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);5 n, ~9 P1 z+ I% y' g! Z
        uint32_t a;
. z) ~0 }9 e4 {# ~) x        ; z% y8 |4 ]! ^6 A
        if(num>64), F  [, T* H1 i$ V5 _! B
        {: L+ E8 Z9 H9 S+ K; s
                a=64;
2 Y5 J, [% D1 }: Y9 ]7 a) O                TX_n=num-64;* l) J6 l# l$ j( I( R
                pbuf=buf;  j9 k- X3 ^' m& d; a/ x- f

7 O1 |/ P* U! ^" U" F$ p) d        }else {" A0 `0 R$ z$ \, O  P( I7 B
                a=num;
% G1 c: ~9 u$ P3 s% e/ ?% q                TX_n=0;* Z0 L) `! J- \  w( V% o
        }9 U! k4 ]; V7 x+ y
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);/ [- l; @* S7 m1 P6 w
        SetEPTxCount(ENDP2,a);
- c' z. v& Z8 Y9 t9 Y        SetEPTxValid(ENDP2);/ q1 Q5 S0 x3 q8 E7 B; o. B' k
}
5 p) L+ q$ W$ M0 s; P
' @( w/ M, \; E// SWO Data Abort Transfer
" W1 w: W9 e) v! pvoid SWO_AbortTransfer (void) {
. N5 [9 h& B* p" a5 Q# Y1 k* T+ l  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));5 {. K' f! u% y% b, s
        //SetEPTxStatus(ENDP2, EP_TX_NAK);: z0 I; j# `  g  J
        SetEPTxStatus(ENDP2, EP_TX_DIS);
6 @1 m2 s% l3 v/ ]! q' ?        SetEPTxCount(ENDP2,0);. Y: J8 a) _" k& A  H
        //TX_n=0;
- u$ u- R8 p4 y' B5 W. U* H+ a}0 G7 z' m# v0 K" c' [( P) d
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
9 w+ W. E1 M, W7 X$ U# k( r5 k5 {# _
6 O9 i; w0 U8 H! n) ~. l( o, H移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
" L6 P9 r2 h4 C' [DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了
# H8 r8 Q% |; j6 n: c! W- i/ i__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
+ d, Q: W# t- b  return (DWT->CYCCNT);3 y+ p6 j' l, t, i: h* q( b, {
}% ~* U7 S+ y: A( C4 u

  r. P( v6 H$ U8 `. l5 a1 k% \1 r. E( ?void DWT_Init(void)
1 k0 Q% {' T' `3 S5 ]{6 ^* Z6 n- d3 O, p' K- R& m
    /* 使能DWT外设 */& d) @) n% d, p: t* `- u
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                % {- H  l  \, R4 I7 Z; Z

; u, L* N% d1 O  ~    /* DWT CYCCNT寄存器计数清0 */
& n) h# w9 [% x4 Z9 q/ D. F; @2 i    DWT->CYCCNT = (uint32_t)0u;
; p. \& A" k' ]6 h4 S; I9 A/ \& J- h( B; N
    /* 使能Cortex-M DWT CYCCNT寄存器 */& e9 f( ^" f7 b  a$ C* M
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;5 S- T9 p8 a# I, G4 o7 z
}
6 b/ P& y7 {: s# a0 c3 j/ `        
1 ]; ]1 R" f4 V
3 ?) K2 C1 |9 \5 b然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率, u! c( c' H$ m' u) q" b2 Y

; |7 A) s3 E3 w. o3 y" B然后改为使用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不香么?
$ O5 E# I$ ~4 s- _6 B" M! Z: s  A4 j声明这个变量static volatile uint32_t SWO_EventFlags=0;
5 J7 P# h/ U  ~0 C% o在SWO里每一处调用osThreadFlagsSet的地方都改为如:
4 B! D/ {+ a9 S//osThreadFlagsSet(SWO_ThreadId, 1U);
4 Q+ K8 }9 I3 HSWO_EventFlags = 1U;
, H  `5 A, z- L2 b! E# B7 F! K, T# d( q* n
1 J, O" r' X2 x9 b) }, P" {
// SWO Thread$ F- {& e2 Q* j4 W0 M$ ^5 G) b
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {( F; ]' V# [7 g
  //uint32_t timeout;; ~1 o& N0 p+ ^3 {* M
  uint32_t flags;
2 U, S6 i9 w: k/ M+ o/ L  uint32_t count;
1 c4 O0 P& n4 x; B. X  uint32_t index;& q: J4 {. X8 \  d) H( z  }
  uint32_t i, n;$ @2 R: d7 A! d- I2 R' B# H
  //(void)   argument;
3 b* h: O5 B+ {( ~: z8 Q4 r6 V; \; ]' ?
  //timeout = osWaitForever;
* S4 b# E/ @2 q: e; E+ `% D, e& U# c% v6 f9 h0 v
  //for (;;) {6 \" c2 h' G4 s% P' ?$ d; S
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);/ ~8 [" V% h; e" C; a6 s8 T3 G0 F9 z
                if((SWO_EventFlags & 0x01)==0)return 0;
8 K: j0 b1 w9 C+ }         
5 P, J' {/ U1 H. g% \* T                flags = SWO_EventFlags;
/ L9 K; G1 L9 y7 ]# A/ _                SWO_EventFlags = 0U; 1 _- {( e4 k( {3 C
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
  R4 T2 P! Q; t; c      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子/ G2 r* w& R$ I' ?6 x
                        ;
7 w4 K: ]4 b3 u. Q  R; s6 H    } else {% k$ ~% u" s( Q/ U5 L
      //timeout = osWaitForever;
8 S# x' Q' k: e3 L2 `) Y      flags   = osFlagsErrorTimeout;5 B4 n" |& K. A) ]# X/ Z/ X
    }
% K* w% z& n0 M: a    if (TransferBusy == 0U) {
* i' @; A8 C+ P, r9 J  I      count = GetTraceCount();
( d7 [- W1 D7 M      if (count != 0U) {
* |3 E- z1 g' f9 }5 f' k& ?4 w        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);; C  b( z: i9 A6 J
        n = SWO_BUFFER_SIZE - index;1 B: _3 j5 T* Q
        if (count > n) {" U5 q$ Z/ y; f+ o
          count = n;
; E; l; K& W4 q1 o& K, F0 M                                        + L8 l  e* l: t/ h& ~: z1 ^
        }' z' `6 M, {; b) b. e& ^' w# B/ ^
                                if(count>USB_BLOCK_SIZE)# g- K, J2 S% J1 |% t0 {
                                        count=USB_BLOCK_SIZE;8 W6 X: y2 B2 k8 z$ N+ P4 |3 F
        if (flags != osFlagsErrorTimeout) {9 I1 j7 |1 U2 ~" ~! W7 f  R) N
          i = index & (USB_BLOCK_SIZE - 1U);
/ S9 q- q5 ^# f7 x& @+ X          if (i == 0U) {
1 ]) \5 \. ?+ Y            count &= ~(USB_BLOCK_SIZE - 1U);
+ u9 C1 k: @+ [  _0 y$ @- O: J          } else {" P- H. K* k" o2 h
            n = USB_BLOCK_SIZE - i;
' I" P) k% @1 N& r& @' N  d, o! n            if (count >= n) {
: l8 s* P6 |; y1 z4 s2 q              count = n;; m6 ?' f* n- E" ^
            } else {
- j+ [; P- B) f4 J0 x! L: ~              count = 0U;
) q) C& H* }6 P6 W5 `1 V' ?            }
- I: E0 K2 ~( F; o, n! `          }  g: a$ ~' w, V
        }
) M1 J8 k2 y( Y! a. d2 W        if (count != 0U) {
' O, a  b! w$ \+ v2 {  s          TransferSize = count;
: e% E' z) p0 m, r          TransferBusy = 1U;" X2 a) q% J; Q4 d; w: ^6 E  e
          SWO_QueueTransfer(&TraceBuf[index], count);
5 Y) F3 f" i( W; Y! E$ }+ f        }
. U8 S3 s- M) f0 |9 g' g( x7 S. a2 t      }
+ d! ?5 K8 E' X( o( R3 a    }
5 u1 U, A, q8 ?2 W5 Q  //}) Z1 {% t" y5 r/ O8 w+ b, p
                return 0;( I8 a) \! J' R4 _* Q: M0 d
}
$ Z, c5 j2 S4 U利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.+ `9 Q$ C: }) V' ]
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
: ?0 ^2 Z0 q9 Y4 jstatic volatile uint32_t SWO_EventFlags=0;+ |+ f- o! V/ N1 C; i1 H
static volatile uint32_t timeout=osWaitForever;- y0 N; ]( H/ |' ]# w' Q# |
static volatile uint32_t timeWait;! v7 z6 e8 b+ y8 a7 y1 N6 k! Y
函数改为这样( R0 F3 S" B9 E  l/ t
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
- ~  [0 j3 @! G( `) c0 s, o! q  //uint32_t timeout;( L: m; T( I) U8 |4 j1 R% ~) ]
  uint32_t flags;5 V  Z8 E! J$ ]" X5 e
  uint32_t count;
+ Q- _% w" Y/ f" ~! _  uint32_t index;
. q+ F, k7 u! j3 b  uint32_t i, n;  r9 F! [5 d5 E2 u  l( O5 |' s4 N
  //(void)   argument;- ?% X0 q. X* N( ]7 e1 Z

7 _; O2 i7 V8 R. N: Q+ J  //timeout = osWaitForever;
0 i1 {( B! T+ y4 f2 {1 _/ L# k2 u
  //for (;;) {
- y6 p- j0 n; |# B    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
( g" v7 j1 ^$ ^' N. ], D  h) x                if((SWO_EventFlags & 0x01)==0)
  T/ A  V9 ~' h. n                {
' Y) k4 H: c2 {- W& S  m                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
0 Z4 {4 F/ Q5 \% z/ V4 l$ \$ x                        return 0;, q2 ~& \/ y4 Y1 f
                        
4 x! W3 C# p- |/ R# L, w                }8 I# h* Z8 b' I
         
9 ?# X2 C3 `% a                flags = SWO_EventFlags;
2 {* c  {8 V" z; R& `9 K                SWO_EventFlags = 0U; * t" ?/ T9 }+ o  E+ N. b
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {9 Q1 {$ p0 B8 y" j
      timeout = SWO_STREAM_TIMEOUT;
1 d- y3 l8 d6 L6 O% J4 `1 k0 }      timeWait=DWT->CYCCNT;- B, S5 C% E& j& O
    } else {
1 L' n! d8 F9 v- L: I" e5 A1 X      timeout = osWaitForever;. l. ~# n0 t- N
      flags   = osFlagsErrorTimeout;
+ \& a1 {( p. D$ p. z* u7 X) p    }# o2 C& X* Z  ?% O! E6 ]/ Q
    if (TransferBusy == 0U) {$ G& D- O. P/ ?3 }1 H
      count = GetTraceCount();' D' ~9 q  x) n2 d' I; u
      if (count != 0U) {6 \4 c# b; ^3 C' [
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);  U4 y5 F2 m- ?1 u7 s8 F
        n = SWO_BUFFER_SIZE - index;
: w+ S/ X! h0 n+ ^        if (count > n) {
* ^% ]; r. y3 W/ @: c; b          count = n;7 C2 r* c4 _( V0 L
                                       
; Q& H7 O# N7 o% C  `- h        }
- v8 X! v' r3 W                                if(count>USB_BLOCK_SIZE)
5 O. a. F% }5 z) x- v, w' B8 l- e7 ]                                        count=USB_BLOCK_SIZE;- n$ N: O* L9 Y
        if (flags != osFlagsErrorTimeout) {
2 `/ _" H' ~: z7 @5 ^; s* p          i = index & (USB_BLOCK_SIZE - 1U);" H& m% s( A* ~
          if (i == 0U) {5 y3 ?0 }8 \% y" N" g8 {9 Z, O
            count &= ~(USB_BLOCK_SIZE - 1U);
# k3 `9 b" g$ O6 \          } else {
! }" J6 r3 H9 n            n = USB_BLOCK_SIZE - i;" @- G$ D: e. ^, _0 h, N
            if (count >= n) {
8 a% s8 q' p2 ^7 v) K7 }              count = n;( S* R& Y  T( Y" j" j" d9 |! d
            } else {
4 C2 b7 I$ _0 d$ G+ e4 n# q. _6 v$ j; Q- h              count = 0U;
" o$ X# r6 {  D            }" t9 r+ \5 J2 u4 E- c% E
          }4 ?( N+ g& x& ?' Q% w
        }
+ N: c; a# d4 l) S' ]& w        if (count != 0U) {3 \& I! U* O: S" R! \0 ^
          TransferSize = count;, ?) X  ?) F$ y5 \- T
          TransferBusy = 1U;
6 X5 S- F0 p) S! D2 T: Z          SWO_QueueTransfer(&TraceBuf[index], count);
% G2 Q7 {) h; k. A% V: [% o, }6 ~$ x        }
# b* T/ _( \. v: c. p' J$ P      }
% D+ [0 N1 c, N$ ^' Y/ V5 F! ]( ~: Z    }
# x' l- j  |0 p% F( e  //}. n2 l& ~" x3 X* @  g; l
                return 0;
- e' y, Z9 u" M3 T$ }: _. M}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了
/ O" t; Q9 d: T5 c/ X" l) K1 ~! }: E  V9 D5 w  X
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,少了这个等待时间,能增加端点的传输速率
& D+ c; I. `' j, g! y1 E1 t; P$ L' X9 X7 U2 b3 V: d9 Y
' Y0 W5 H- q1 I
int main(void)$ F) ?7 r9 h, |4 b6 q2 F# R7 A
{; e' ~6 S3 ]; A# W. `
  DWT_Init();$ a* K) Z; J% q' j- R6 z1 _$ [
        DAP_Setup();
1 k/ [( q( Z! b" f  USB_Interrupts_Config();
+ U4 I# {) A/ j; _  Set_USBClock();
7 \8 X, b; h; r3 M  USB_Init();( y4 \& L* a- S8 J% P/ o! v
        //TIM3_Init(35999,0);
( W) M3 D; k+ N. I& a4 m% `        //TIM_Cmd(TIM3,ENABLE);
  t) H6 _# @3 C7 _. U+ Z        
% p& ]5 f  O5 Y/ M1 g        6 z5 N+ U, q2 p% `
  while (1)
+ ?: l6 O% V8 C0 k- I  {8 C% Q$ _# A, E  v6 K8 z) c$ M
                DAP_Thread();' ?7 k5 {. b% R  K- m+ d4 x  \
                #if (SWO_STREAM != 0)
+ r5 y3 o# J7 r5 w3 E  O/ O                SWO_Thread();
2 U& G, ?2 |, L5 O; ~                #endif
1 i9 u$ i6 w  E$ @% B% v  }
% k; {6 p7 x0 l0 h}
2 D+ a3 @, c' C6 }6 j7 j- R7 b
( ?1 y2 @: q/ A/ }3 A# l对于DAP_config.h的IO配置我是这样弄的
: I6 ?* b! g$ D1 Z, a///@}
' t$ F1 H4 F+ D+ ?4 S! \& ^// Debug Port I/O Pins) k* w) B4 p$ Q/ ]6 Y

6 W7 q! f, {( G- p" g// SWCLK/TCK Pin                GPIOA[6]
+ f( J& [) j+ f! L6 t#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
  a0 u! W6 `  n: H! {) W#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
' U$ n* k4 d8 K# a( F0 |: D
9 _$ j' H* w6 v2 _4 C// SWDIO/TMS Pin                GPIOA[7]9 \& }3 P. r0 Y  M
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C9 P( C5 V! @+ O) _
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C2 Z- M' A, g( w
7 s0 y( E2 z( \! U( o* W; l. i
// SWDIO Output Enable Pin      GPIOA[7]* M5 u' W, ?$ p
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
. q; a/ \( `' q$ p& z                                                                                                                                *(uint32_t*)0x42210070 = 1; \* }' }6 r. ^- ~# u: c( K5 s$ i3 U: \
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
9 [, e/ _4 L: ~" j0 S: J( X7 u                                                                                                                                *(uint32_t*)0x42210078 = 0; \; \+ ~6 L( b! ~% R4 Q7 u
                                                                                                                                *(uint32_t*)0x4221007C = 0;}
" @& T5 {6 x" n+ S# u  P: C* i9 h6 g  C( E
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
' D: h3 }: [7 Z  _                                                                                                                                *(uint32_t*)0x42210070 = 0; \2 m& N7 {2 z0 a, V% B% R: P4 J
                                                                                                                                *(uint32_t*)0x42210074 = 0; \
' v  G; d0 w$ G% f" u. W& S5 o7 ~& r                                                                                                                                *(uint32_t*)0x42210078 = 0; \. S# F; ^# `6 |$ G3 a; l
                                                                                                                                *(uint32_t*)0x4221007C = 1; }) Q* [- {1 R- }4 ?4 Z

9 g+ Z% y" [7 f' P5 E// TDI Pin                      GPIOA[8], K% v2 @+ l0 M8 J
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0$ M3 Q+ t  X, @( V$ }) D2 O- w
#define TDI_IN                                     *(volatile uint32_t*)0x42210120( \$ M2 `: F5 T) R) S& |. X% J/ u3 {
( u5 o7 ^2 Q5 F( W$ u
// TDO Pin                      GPIOA[10]
8 F% S' a: T! U& a5 [& @9 Z# z4 ~- z; W#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8$ M2 j1 r4 C' R& u7 h; L
#define TDO_IN                                     *(volatile uint32_t*)0x42210128" S1 G  `+ ~/ L: H- W
1 e% q; S- [4 K( d9 Z+ @; l( k# y
// nTRST Pin                    GPIOB[3], R8 {# C) u8 Q6 w3 G
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
7 }( ?" a! G4 m$ \+ H#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C3 F# |( B  B4 o/ j9 n. e/ F8 L

' w3 h1 s% T) ~+ P2 [// nRESET Pin                   GPIOB[4]
6 ?& F/ {% N  v7 ^% x0 d: `0 l2 Y#define nRESET_OUT                                 *(volatile uint32_t*)0x422181906 L# C  {2 V% y# M2 p
#define nRESET_IN                                  *(volatile uint32_t*)0x422181101 O4 L5 E! Q, s3 c" c4 @7 C
3 T! c  {! K4 K8 n8 t9 O. |
// nRESET Output Enable Pin     GPIOB[4]; i, H( m$ o1 K4 S5 C1 O# W
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \5 e( V# r% U" R, r9 \8 S8 d2 r- l
                                                                                                                                *(uint32_t*)0x42218040 = 1; \
, ?0 Y2 W. X. n/ R( V8 I                                                                                                                                *(uint32_t*)0x42218044 = 1; \
) `2 m  E; ]% V$ o  h                                                                                                                                *(uint32_t*)0x42218048 = 0; \1 p* {) ~+ j# S7 ?  B
                                                                                                                                *(uint32_t*)0x4221804C = 0; } . ?$ y$ O" l" e. O" x" t- T' o
5 }: C* d, n( }4 ~" w. o: j
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \( Z+ e. L' l% E) u" ?8 v  K
                                                                                                                                *(uint32_t*)0x42218040 = 0; \& _2 b/ e9 K. z1 d/ ]
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
3 t  R3 }0 e( k: g                                                                                                                                *(uint32_t*)0x42218048 = 0;\
, L% J+ ]& @' a: |1 X1 V5 @                                                                                                                                *(uint32_t*)0x4221804C = 1; }! S7 ^% V4 k9 C$ ^; T
2 W+ o0 y  w% ~! n
5 S- L0 ?6 j5 l
// Debug Unit LEDs
8 U7 W4 `: X  A
. \, I; I) v! ]& N4 e1 M// Connected LED                GPIOC[13], [; o/ @" k/ C- f3 }
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4+ Q: e) a, }  {; ~$ J) p; ]& B
#define LED_IN                                                       *(volatile uint32_t*)0x422201340 q) M' D( N# r8 `' {2 R! |- d: v
$ `) ?& i+ }( g  @1 |3 p1 ~4 A, W
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \8 u6 a8 e: O% P+ w) H, L9 G
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \( ^& l$ R* U) i- L( c& Z8 d8 y
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \  T, G" G5 O0 ?7 s- M4 f
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \, ~6 W/ z) ~# h* c" ]5 m, U3 l
                                                                                                                                *(uint32_t*)0x422200DC = 1; }" }- c; P  u* b9 F: ]
// Target Running LED           Not available6 l+ g0 q8 S/ g
. M" S7 B- o9 ~* N6 ?
// SWCLK/TCK I/O pin -------------------------------------! f7 \6 L5 |# u' [8 ^

+ c3 [' b( q6 M5 B) M' S3 S5 D" H/** SWCLK/TCK I/O pin: Get Input.4 p5 h$ W# J: b" ?" h- Z& J) R
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
% d( V$ U- A) h*/1 T* |, R# _0 B1 b. @- k. x
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
# U5 z& ?1 H( m+ D" n  return (SWCLK_TCK_IN);
) h7 r& {7 `! }}
1 m2 N7 F2 }/ w, ~7 K+ x2 M/ V  E! r$ O1 u: `" c( R3 x
/** SWCLK/TCK I/O pin: Set Output to High.
6 `4 V/ ^: N  p; g6 iSet the SWCLK/TCK DAP hardware I/O pin to high level.
( a% M/ m- D; g( ^*/
* `8 T8 j& _$ _9 Y! H* v( ___STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {! z( w+ T9 W* R9 H0 M* k- i1 j
  SWCLK_TCK_OUT = 1;3 e" X) ~7 K" w! f5 o; P
}8 D" S* f. h- Y. n& {/ V, n

1 M! G3 N: F6 t- s0 C7 j/** SWCLK/TCK I/O pin: Set Output to Low.
5 Q  e% q# W9 `Set the SWCLK/TCK DAP hardware I/O pin to low level./ Y4 Z) `- G- R( w" R" u( S. l. }
*/
; ]" x* Q9 g; G4 O__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {9 e: l7 C- g# ^7 ?( e3 O0 s0 }
  SWCLK_TCK_OUT = 0;. j6 `# S+ O9 k& l
}; P, i- c! l. R* U# x
5 n" ]7 O  w  b7 G2 u
4 p; D$ R9 W" B2 s# {6 a
// SWDIO/TMS Pin I/O --------------------------------------6 ]( o9 W( _% w; d" r* c% z* X( Z" J  \
$ Q: ~$ R( K5 E) F; e
/** SWDIO/TMS I/O pin: Get Input.3 V( d9 k$ t  H% J5 R- R
\return Current status of the SWDIO/TMS DAP hardware I/O pin.$ n8 \1 `1 @) M& t& I: v+ q4 |
*/7 B$ a$ k1 w" [$ k% }* I
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
  h- A0 g5 M9 }  return (SWDIO_TMS_IN);
$ x. K( v0 P3 ^/ E9 U}8 F5 [" D' D& a) T/ u
8 \9 V0 i8 Y- j/ t( t+ M/ a  L
/** SWDIO/TMS I/O pin: Set Output to High.' f0 h& G2 W8 x
Set the SWDIO/TMS DAP hardware I/O pin to high level.
7 r, ~1 |2 D. b& O! F0 P' h- y. j4 P*/
3 m7 Z# @0 q, ~  F__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {
6 b# s% U1 J' {* G- G  SWDIO_TMS_OUT = 1;* y- Z2 B; Y1 V" Z( f; n; h0 ]' g
}* z1 w0 j  A4 }  y0 x3 Z* l; v3 `

. X( O& o: Y$ H: Z/** SWDIO/TMS I/O pin: Set Output to Low.3 L* N  W$ m$ B5 a* F  e' o! K/ u+ k
Set the SWDIO/TMS DAP hardware I/O pin to low level.6 h2 G: C* V9 m# q/ _- t
*/& G3 P" X3 Q+ Q$ n/ Y9 t$ b
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {; J; R; }' v$ W. x( i2 d
  SWDIO_TMS_OUT = 0;; [, W0 q: {2 V8 X* P% o
}+ x3 ?% ^8 ?! H
3 Y9 E+ G. Q$ N) i: p
/** SWDIO I/O pin: Get Input (used in SWD mode only).: o, d! Y, h% ~  `/ i
\return Current status of the SWDIO DAP hardware I/O pin.
! t# \/ ~) y6 f3 g*/# @- E6 ]  t6 P% l6 `
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
% ]5 p- L; w% w4 V0 z  T# G+ T6 s  return (SWDIO_TMS_IN);
  r, d+ s! c' l  t}# ^* b0 h8 r% a. g6 u6 f/ Z9 F

% z! Q6 h' Z- E% v8 G/ G5 x/** SWDIO I/O pin: Set Output (used in SWD mode only).8 G; b1 r' r/ U: y, t1 u8 E7 s8 v
\param bit Output value for the SWDIO DAP hardware I/O pin.0 u& Q/ p& i' e; {; P% q% c3 w
*/( ~) w. Q& N, A, p* I" a8 C* @, ?8 _
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
8 k) T, [  J" M  SWDIO_TMS_OUT = bit;1 O5 K9 M, u$ V% [; q& h( ]" [
}
* B! y3 B! `! \
# W% }$ O% Y1 l1 @/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).& K' N; O: z% N+ z( a
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
) N: A, |- G0 fcalled prior \ref PIN_SWDIO_OUT function calls.
7 a$ Q' p2 P/ `8 c! }5 c3 J2 K$ g*/
, Q4 {! }9 h) E* T( o! d: F6 N__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {5 m0 ]% j1 C3 a6 f7 g5 z, @. V
  SWDIO_Output();
2 U- ]" j( t  X" }  h}
* h3 j* C* U( i" M
1 |6 P; R+ m* `0 O/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).2 I( ~5 k' w# ?; f7 W2 c4 c; D
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
5 N' k# @# k! o! M4 S( y' d8 hcalled prior \ref PIN_SWDIO_IN function calls.* Y/ w% o# E7 q9 V. y
*/
# p7 U$ c- s! U__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
' F0 A; c( B$ n; X" I9 W; x  SWDIO_Input();
, n7 h- i8 M/ c2 H4 B! D% ?) z}4 c6 M. A0 I- {) R" f

  ]; g5 @3 F2 z1 i! J) i9 M楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的7 P7 \  s9 Y8 v* \
即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
: g0 m. j* {+ q# g
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似技术帖

官网相关资源

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