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

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

[复制链接]
radio2radio 发布时间:2018-5-31 15:47
阅读主题, 点击返回1楼
1 收藏 45 评论417 发布时间:2018-5-31 15:47
417个回答
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,希望做一个,让复位时给一个低电平复位信号。
7 i8 g% T' \0 I+ ^5 _5 z
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
( |! J' z3 ^7 j' b% W3 [除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

" A9 w& v: i3 J( d6 |) j! g我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。6 R1 a) X$ \1 f4 Y* Y' t' K

4 E* R9 C5 r; Y7 Q2 F' d. Z1 O+ F, d软件复位是另外一种情况,需要向目标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
/ R4 A+ k6 V2 q+ ^可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
5 Z0 }+ M. y$ ?" ~. {5 k1 a
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
3 `& }9 A- ]- r  L' r( k+ o你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。, e9 r1 ^; R  \% H

- x& |2 t1 m1 l' j你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
. E& h" w6 i3 D9 F2 u或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
! S" i2 ?% V4 Z  t4 X8 b+ o; b; c7 o/ L9 `. w6 h

  K  ^& }9 c8 a% ]' G& L
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
$ ^$ t7 Z1 D1 v" g% T- J
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap ! ^; l1 X8 l0 T8 T& L2 E6 E" v$ z! g  }2 @
起点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系统,轮询执行
, q) f4 g4 K2 F/ M# `# F/**" h3 e6 _: X% z- ]8 c6 k% o6 I
  ******************************************************************************" y7 Z( ?1 |6 W
  * @file    usb_endp.c; f. Q: f& O* u  q" m  P. P
  * @author  MCD Application Team' R7 Y# c3 O1 q5 Z5 a; I# k
  * @version V4.1.0' G7 g( f/ H! o. W. {* g! |1 s
  * @date    26-May-2017/ e0 _' C+ ]; ^2 D
  * @brief   Endpoint routines& u, w$ T' F7 `+ @# F$ U/ L% u+ w
  ******************************************************************************' j% _7 d. U) r5 l0 @  v
  * @attention/ M3 O8 i; s! k
  *
7 ^1 v4 s# j$ @* Q- y% c3 C  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
0 J" u! j5 B5 X  s. k  *1 h4 Z+ o8 o9 I5 G: C; z3 A
  * Redistribution and use in source and binary forms, with or without modification,
8 V" w) K/ W0 j  * are permitted provided that the following conditions are met:
! W, j# h' p1 }$ Z  *   1. Redistributions of source code must retain the above copyright notice,6 E' J9 _1 j( s7 \6 Z; w
  *      this list of conditions and the following disclaimer.
2 u5 t7 L/ a4 y) N+ ~2 K  *   2. Redistributions in binary form must reproduce the above copyright notice,
9 N+ l2 z5 u+ p5 m  z+ P! y# R  *      this list of conditions and the following disclaimer in the documentation
6 `' g, q6 [: V2 J0 h" X  *      and/or other materials provided with the distribution.
% R* x- ^# G: Q0 k1 f  *   3. Neither the name of STMicroelectronics nor the names of its contributors  o/ P! E  Q1 x+ m
  *      may be used to endorse or promote products derived from this software
* S# j0 f/ y5 V7 u4 t  *      without specific prior written permission.
3 R3 x6 F* c; _  *' ^. `% o- [( K
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
' O* d! }7 k; _+ x: A! q3 [7 F  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* _* H) f  X4 l+ L  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE5 d* U7 v5 {) w* ]/ V
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* q( q1 d$ Z( T& r$ T9 R
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL8 o+ r9 q. o4 |
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR; y6 i5 H7 Y' s( H5 p" `
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER! q2 z4 s" ?% d% t: Y6 {2 f
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,3 x" Q0 [: C+ G/ E3 |+ P( @
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE9 i8 F5 j2 m" O& T. ?
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5 n$ b9 N& S3 |5 r" b' E  `( q7 A  *
$ ?* \0 K9 @4 U8 Q6 c/ t/ Z  ******************************************************************************* B" ^, K) _+ z% Q9 P; m
  */) r9 e: e/ }* R( p0 N
0 }3 t+ j3 ~& J& h9 |4 @. E" g8 l

: d# p/ N6 J: G  z7 F/* Includes ------------------------------------------------------------------*/
  y; b( U7 i# l* ?0 x#include "hw_config.h"
3 g9 S7 h% B' x, q#include "usb_lib.h") a6 [7 s1 @! S) i* l
#include "usb_istr.h"
$ \8 Q! ?$ R8 |; u& @, a#include "stepper.h"3 l8 M+ v2 J, q. g: t
#include "string.h"
% [' I8 P% `, z+ W# Z+ T, `& g# L- K
#include "DAP_config.h"
" r  Z, D9 B4 l2 Q( S( v#include "DAP.h"
- v5 n+ m: B) d- h% H7 d9 {
. n4 R( v, E1 y' O# p; b& j) R, A$ g. g& t9 d: x
/* Private typedef -----------------------------------------------------------*/
7 @2 |, m) K+ z& p/* Private define ------------------------------------------------------------*/
) @9 s- M3 j& t. G* s* t/* Private macro -------------------------------------------------------------*/
- M/ |4 B3 ~/ K/* Private variables ---------------------------------------------------------*/
- X3 g% e( g- R! f7 ostatic volatile uint16_t USB_RequestIndexI;     // Request  Index In; |5 [  E/ A9 Y) N
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
# a+ ^  q- G$ _2 f: v0 S( Xstatic volatile uint16_t USB_RequestCountI;     // Request  Count In; Z7 g, U6 X' B. X4 {6 R- [1 ]
static volatile uint16_t USB_RequestCountO;     // Request  Count Out( }" G) P# ~! r
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
: F! [6 h& M5 F! P. r; k) C4 w. u2 |- o1 Z% o9 U1 ]
static volatile uint16_t USB_ResponseIndexI;    // Response Index In
- g, h$ c. N4 K% h2 Z( V7 N' e- rstatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out
. y3 n6 F0 {4 }5 c* V- B' |static volatile uint16_t USB_ResponseCountI;    // Response Count In
/ ^' W! ^7 ~- P: Pstatic volatile uint16_t USB_ResponseCountO;    // Response Count Out
/ S" j& l7 l& ~. Jstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
3 L  K: R+ L- b1 Q0 Pstatic volatile uint32_t USB_EventFlags;- s: o4 F; C5 |7 J! A$ v5 A

* M4 y# Z/ F5 ]. s* c6 t( h+ ?2 _% qstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
. Q# ~, v/ U- `1 }static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer+ e" W/ u6 p9 V$ L( E1 Z
static uint16_t USB_RespSize[DAP_PACKET_COUNT];5 q# ^; M! q  d5 a2 X+ ]
# x# N8 p* ^8 E7 K5 t5 [  I
/* Private function prototypes -----------------------------------------------*/$ C  E% k3 O  @
/* Private functions ---------------------------------------------------------*/
2 _4 w! V" `' m( n& H) q; c/*******************************************************************************! k2 o, a; K5 r: e) R' A
* Function Name  : EP1_OUT_Callback.7 M, @+ x3 V. ?0 i: R# Y
* Description    : EP1 OUT Callback Routine.( G, q) n7 x  T6 i$ h+ R3 s) n
* Input          : None.
8 T4 j' k' Z2 A* D! X* Output         : None.5 n* \0 ^2 N" Z1 R; G
* Return         : None." Q( t# d$ M. }( ?  m, ]# _9 s
*******************************************************************************/6 E7 D% c& J1 W( s; w
void EP1_OUT_Callback(void)  I' o9 m- f4 ~5 A! w$ \, \
{
) y* ~: Q! Q5 v4 v; ^        uint16_t n;
/ v4 H' ?* v- X3 B/ ?9 l7 p0 ^) }. @$ d- Z0 T. V
        n = GetEPRxCount(ENDP1);
  X9 N2 ^6 N4 l- i, D        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);: B' F! x- `- s
        if(n !=0){  {- D, f7 F4 C& l6 M, U9 I, |. b+ }
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
8 _5 d9 H- Q% z1 a1 G                        DAP_TransferAbort = 1U;
" b  ]  N- |2 X( H3 A2 h                } else {
9 _/ F! B( z6 T+ w# o" m, I                        USB_RequestIndexI++;8 [0 b( G- c, H  ~' U
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {' S2 F- H7 X/ G/ C! t7 e9 z
                                USB_RequestIndexI = 0U;
4 n9 A4 A( X1 a6 j      }" H0 o' U4 ]- ], ]
      USB_RequestCountI++;/ G+ s" l8 a( O. h# H# N
        USB_EventFlags = 0x01;
$ |) h, w1 T0 z/ \0 v; H; ~/ r    }3 b# B9 q2 q. c
        }        0 w: A) a, H( L' B  G
        // Start reception of next request packet! [$ a% `( |5 }
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
1 {: ?9 m7 [" s, w0 m                SetEPRxStatus(ENDP1, EP_RX_VALID);
" x2 J. ^* a8 [# g        } else {1 ]; g7 t/ {% y7 P: f$ _2 c
                USB_RequestIdle = 1U;
+ d7 |' ^$ C0 u        }                        
' N1 `  |. ^$ B& Z3 _& {! Z9 T}
0 A( S* l+ ^( h0 V: x* p1 k0 P
: `5 N" O* _6 m% }( Q; }/*******************************************************************************: E, {: I" f& b
* Function Name  : EP2_OUT_Callback.* x5 M/ T* q  k+ S0 {: t& s6 V
* Description    : EP2 OUT Callback Routine.% n* X3 p! [# G- R! n4 q/ G  q: h) l
* Input          : None.: {0 R9 L; x$ C6 S
* Output         : None.. N8 W8 l. c# K3 ]  @
* Return         : None.
; b5 i/ }  Y9 \* C. a- Y*******************************************************************************/( C" P& U: n3 N' V; k0 `
static volatile uint32_t TX_n;8 Z" d+ z/ N1 P! h1 i- }
static uint8_t *pbuf;
" ?& {& F* M0 N( kvoid EP2_IN_Callback(void)' l) l0 u9 z% p+ D/ V( M
{
3 G% g* {  y* T- O6 A6 q0 u! n        uint32_t a;. J& Q+ k3 r6 [  K  g4 I) ^
        if(TX_n>0){0 D: [: `7 a3 f. s. K
                pbuf+=64;
, H# K) p/ e" V1 @1 G                if(TX_n>64){
: ~% k; a. f4 Y3 }* x( ?, E                        a=64;
: L9 l3 j7 I3 ^( C( v/ T0 q                        TX_n-=64;2 }( w  R) i" B' l& d" ^7 H
                        
( b7 a! V6 W! a6 w! }                }else{
( ~; {% _) }0 J6 B5 j                        a=TX_n;$ j7 W# c1 t1 p. J2 a; W0 P/ a) U
                        TX_n=0;
; Y/ w" Y- ?/ u) R+ R                }8 _2 k9 O+ L7 J$ }* S  \2 `
               
9 q# P$ \- v5 X( N: V3 c        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
1 ~# P8 ]+ o+ [. ?4 k: Z8 T        SetEPTxCount(ENDP2,a);
# r3 z" g- H& A- B0 m7 N               
$ g; U9 C; p+ w  p5 H! _        SetEPTxValid(ENDP2);
2 t- n9 C  e  w% n4 D$ f        }else{6 B/ U! X/ j. K5 ]# X7 X. N) k: S
                #if (SWO_STREAM != 0)5 J% _$ _7 S3 L: z( q& _5 z
                SWO_TransferComplete();  ~& P# N" R$ T/ w: k+ b* C
                #endif
3 q9 f7 p; d; O' G        }- F4 a- A* e4 z4 ?7 t2 X7 \
}8 v8 e& K7 w$ _- }
' w- l' }+ |( X$ k$ b1 R6 Q& a: G
/******************************************************************************** v5 d$ L  O! r3 W' ]
* Function Name  : EP1_IN_Callback.+ R+ q1 ]7 R5 Q, I
* Description    : EP1 IN Callback Routine.
8 q4 h5 X3 v+ k2 I" B* Input          : None.
" t2 d) N8 y8 Z. p1 `* Output         : None.
1 w6 ^& q: p" I1 u) A+ }* Return         : None.
' j1 J: Y7 X. b: y4 T5 t$ N*******************************************************************************/
7 m/ {7 E- p7 n" N7 A( K) Gvoid EP1_IN_Callback(void)
! z  S% p4 P7 t& g5 y+ F{
% i" v, ^* ]( i3 ~8 d' ~    if (USB_ResponseCountI != USB_ResponseCountO) {. T3 }9 J& X# z
      // Load data from response buffer to be sent back
0 k3 `* \7 G! j" K. l% D: o; _1 @                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);8 g# p' ]" r5 H% J7 W% D; N
                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);1 r* v# _  X. K7 J$ |. [
                        SetEPTxValid(ENDP1);                        
; T- }5 a& E0 y- M0 A      USB_ResponseIndexO++;
4 o4 b1 m- D4 _% h8 @+ K      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
) }4 O$ I* y3 [7 I' b7 ^        USB_ResponseIndexO = 0U;
/ R% @8 ]$ E' _6 }" I3 A( B, c( {/ o      }5 P, i$ q' \$ h$ f
      USB_ResponseCountO++;
& }5 j% a  a0 H    } else {
" A; {9 U# x. m2 Y  y0 d8 G      USB_ResponseIdle = 1U;' k! p0 @/ m7 u' j
    }  8 e& c8 r" h  B7 b! Y
}
9 X: e1 J5 U3 U1 {4 A8 _0 c  O
% f2 u! y) u0 K7 S3 i' H9 r; B// Called during USBD_Initialize to initialize the USB HID class instance.+ i: Y0 T" Q% R# w' I( t- H
void DAP_FIFO_Init(void)
" t8 |4 j5 n; h{; I9 n1 w# a: Z4 f
    // Initialize variables
5 W/ n9 a0 D; x/ x4 Q1 w    USB_RequestIndexI  = 0U;' Q2 r" s7 h; K' A
    USB_RequestIndexO  = 0U;
6 {4 |! @$ T8 _9 {7 l    USB_RequestCountI  = 0U;0 g6 U% Y. H: F, j$ J  F
    USB_RequestCountO  = 0U;9 p. H9 a( r2 y2 F; T
    USB_ResponseIndexI = 0U;0 E$ x& \- M" X; P9 t9 m; c
    USB_ResponseIndexO = 0U;3 ~! }, G4 D# j* Y- ~( Y+ b
    USB_ResponseCountI = 0U;
" f9 j1 |4 k- K: @    USB_ResponseCountO = 0U;( Z4 A. t* o: }0 @
    USB_ResponseIdle   = 1U;- ]; j+ X; Q' G& E; k5 u; L
    USB_EventFlags     = 0U;
) [- Z. N8 F! c5 R- b" p$ z) x}
6 I2 w6 W5 U. l4 j
6 O' D4 m! x, k9 ^2 juint8_t DAP_Thread (void) {
, P; [* S3 q* ?) y  uint32_t flags;
0 G+ Z; c! Q" P5 r: Q* }7 O7 f6 D  uint32_t n;
* N7 r# w- h3 b6 P: b* X
/ i. n5 Z2 k1 R% }8 D  //for (;;) {9 E! t! v2 l( K" y" a/ o' S
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);: a- \/ @# {: n, h/ k1 d# \
                if((USB_EventFlags & 0x81) == 0)
2 E2 C( a0 r/ t$ `3 H' `0 Z                {
! s$ W! s5 ~6 S6 c$ r( |                        return 0;
( j& P2 ?( c7 I# P                }
" R. v$ b9 \5 j                USB_EventFlags &= (~0X81);* H8 v: \0 v* @9 o
               
! Z1 l1 _5 y# H5 B7 y$ a8 l/ ]                                       
2 {3 M  g7 f- G, j& b    // Process pending requests+ G0 H" W; z. p
    while (USB_RequestCountI != USB_RequestCountO) {# j9 B2 r- R: D
                //if (USB_RequestCountI != USB_RequestCountO) {1 Z1 W: \9 v) }, `  q) F4 k% B
      // Handle Queue Commands
- a6 l& v. ?7 n$ @; X1 ?  Y. r& R      n = USB_RequestIndexO;
! ?, u, O6 x2 M. M0 k. e! u      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
+ l0 e6 E; h0 c# [! _% ^! E                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {5 W. {* H0 Z% B1 {5 W2 T- `: D' B
        USB_Request[n][0] = ID_DAP_ExecuteCommands;
% |4 d! i' w  u+ L        n++;
# L3 H# U. e: m# i; c' D" {        if (n == DAP_PACKET_COUNT) {1 ~; ?0 h# Z5 G6 Z: t
          n = 0U;$ x9 }; r7 i1 h4 |& F
        }8 V) i8 O  u! H' P/ |" F
        if (n == USB_RequestIndexI) {
% [) ~+ t$ J4 ~; \          flags = USB_EventFlags;' n. v% h( h# Y- f' M( b1 }; q
          if (flags & 0x80U) {$ I1 s- [. h$ l
            break;
( K( |( J+ Z" _  ~# w. Y8 y          }  P' d$ T- [! Y/ R* a0 a# J
        }: B5 I; C( V8 e2 J, q
      }
' n5 M: @9 G2 Q+ G# \' {
% C" Q: k3 J/ S. A* E' @      // Execute DAP Command (process request and prepare response)) W5 i+ V1 t* q' \- b; ]- T( P% M
      USB_RespSize[USB_ResponseIndexI] =6 }$ w" F5 T' b
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
" v' o2 f' h& k4 `
; R6 F) a. s$ u1 F- z' t      // Update Request Index and Count( f; N# b  Q; s2 a) _3 `
      USB_RequestIndexO++;
( K3 N# m. c7 v9 f      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
. U' Z5 Z# h  V2 ]4 ?. @        USB_RequestIndexO = 0U;
) P( ]6 u3 {& i1 {+ z6 g3 C      }
! l& F* o" _) L& Y( `* M) A      USB_RequestCountO++;
' x0 D8 p1 n& f  M# J% x
) P, g0 C2 }2 m' R; o7 W$ Q. f      if (USB_RequestIdle) {* j6 `- t) `4 n& R3 L0 U. `
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {. W; u. g# C, ]( D: U2 b
          USB_RequestIdle = 0U;' w- D. X" C& y3 d: }- n, M
          SetEPRxStatus(ENDP1, EP_RX_VALID);
8 @2 B* n$ o, ?" @6 L- F) y        }
% a1 l8 e) _$ d0 C) F" a      }
3 W/ S5 S9 g. [. \/ A* T6 \& Y$ f6 Z6 G% N. S4 ^
      // Update Response Index and Count$ r* X/ O) Z7 E& B7 f  V
      USB_ResponseIndexI++;
7 Q6 A. C0 Q' d  x* t4 v      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
) B; r: O6 S8 P4 @: I( }; Y        USB_ResponseIndexI = 0U;, R1 J9 i, g6 N9 \8 X
      }! m2 a3 p' Y" v3 b, j
      USB_ResponseCountI++;
/ ?# ^1 C7 n! R9 S4 X3 ]; d3 O3 Z- @3 d3 d
      if (USB_ResponseIdle) {
1 d4 E6 s# q5 [, F4 d        if (USB_ResponseCountI != USB_ResponseCountO) {
$ r6 g/ ?! p7 B6 ?! q( d6 V          // Load data from response buffer to be sent back2 V( F6 A  f! T) q8 c4 ]
          n = USB_ResponseIndexO++;
% I" A- A" N- A          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
. o/ ]% v5 {; e" N            USB_ResponseIndexO = 0U;$ e. H0 W- g2 q
          }
3 N& U. N1 A3 L1 O: [2 L          USB_ResponseCountO++;
0 ~; k, e+ A3 B" P5 s          USB_ResponseIdle = 0U;) |$ |! b1 C; `8 c" n8 X" j
          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
1 X* r) D% ]. D. W7 @: J                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
( x! m' Z0 k* e( n; M                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
& E2 q+ @+ v/ {" }                                        SetEPTxValid(ENDP1);
/ v( u" R' \4 o! Z) j        }
5 y, ?) v- }( L% y3 Q' v1 O& f# I      }
0 g8 Z" R2 k: A  b" e+ c    }
5 z- R; a$ D1 O& R        return 0;
: X' F4 M% `6 G* C' ^}
* ~) v. d9 `1 F! z% N+ J' j( S" Q/ B4 |7 C
// SWO Data Queue Transfer
3 L! ?. r  {8 b7 M0 b$ l//   buf:    pointer to buffer with data
0 D2 |6 A7 P8 i8 X5 Q6 u//   num:    number of bytes to transfer# C  F( W8 s, x! B7 t# E3 C
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
5 C7 h0 z  A2 j1 i# _1 u3 t. m! z  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
1 w6 [6 u- M0 k2 o0 g- k        uint32_t a;
2 Y, P0 t+ i1 X+ x& e        * I7 Q% c! a1 e# l
        if(num>64): W3 n7 V8 c! I* L$ p2 P
        {( G, ]7 d- o: u& G9 L6 A+ l
                a=64;( |' M5 q$ t  [2 V2 w  @8 ?3 ]
                TX_n=num-64;, G) e+ x% v  _5 W9 o$ [0 @
                pbuf=buf;
  R  V; @% q- p1 s8 G: t' d* I# I% _" k/ O8 x1 s
        }else {
' R0 t- X% j. I# u, X! u# f                a=num;3 u/ z5 ?6 |+ K% }5 ?* o
                TX_n=0;
2 N7 ]0 x' y9 n: d$ P+ }        }
- o7 C2 t5 K0 [8 Z2 X        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
8 N  J0 C) {  u  X# _( G) X        SetEPTxCount(ENDP2,a);
+ I( W7 p" Y" o  Z5 M) Y) I6 _        SetEPTxValid(ENDP2);
  S$ \8 u0 Z2 r}  f0 u9 d. _& [+ ~* o
9 g4 F- N* g: K; p
// SWO Data Abort Transfer* F) H  O+ m  w& X, E7 v
void SWO_AbortTransfer (void) {5 ]8 L' O2 o) ?3 X! l& u
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));4 a3 [2 W/ M5 J  R
        //SetEPTxStatus(ENDP2, EP_TX_NAK);
+ F0 I& F+ z; h/ a        SetEPTxStatus(ENDP2, EP_TX_DIS);
: I  H% D9 P8 m        SetEPTxCount(ENDP2,0);
( ^  i" `4 y& j        //TX_n=0;* ~5 S6 b# @* }/ w/ t  r
}
0 V4 o' \: o+ N  M: V/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
3 p' G1 g, p6 c5 P( t1 ]
1 {1 b4 d* r; M7 Q( 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时感觉速度还是可以的,这能体现批量端点的好处* t$ L4 T0 b! k9 q6 o
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了7 z; j+ S) n2 R! C) K' m
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {- r' W6 e( S) R9 z8 V( a
  return (DWT->CYCCNT);, |% Z! c" O, u
}$ [' W% Q0 \6 k0 Y7 L7 n

: i, ]# S  I: D# @( g( w8 b7 N: Q" qvoid DWT_Init(void). b7 Z7 Z, q) k9 u! Y
{* w, x1 h1 p( d' ^
    /* 使能DWT外设 */' B9 h4 n  N1 @4 G
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
; \, p8 H' c! X( u, a* q4 X
( D4 C1 ]! j, Y$ ^- H  ?$ E2 B    /* DWT CYCCNT寄存器计数清0 */
2 z! f" S/ s9 T# _' \2 A+ V    DWT->CYCCNT = (uint32_t)0u;
: U, L; C$ P, d5 K5 k# j& C! L5 h! O9 X  Z4 G
    /* 使能Cortex-M DWT CYCCNT寄存器 */
. d7 M1 ~" {1 R7 h; h    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
/ n! `/ F/ K$ ~& q& S; h9 {  ^2 R9 X+ D}
1 y( w5 x5 y* H0 @: w" v        4 J: Y7 g# }' S" G! ?2 M7 `

) ^! O& k0 L1 J% X然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率- }( G# T9 p1 O# ^, v- ^
/ B( ^# E3 C+ y' r5 ~' V
然后改为使用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不香么?
* C$ v- W, R9 l声明这个变量static volatile uint32_t SWO_EventFlags=0;0 {" n& X( X2 H: B
在SWO里每一处调用osThreadFlagsSet的地方都改为如:6 v7 _! U) `- h: B$ R+ T
//osThreadFlagsSet(SWO_ThreadId, 1U);, F4 ]# @- F( B  ^% D# S
SWO_EventFlags = 1U;, W' m2 u+ p: @+ w, W( W

5 t: C6 Y) a5 x6 d8 X) i* l% n% K- y: M! S
// SWO Thread
! ~& _2 Q# T/ U5 z: o1 a/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
( l+ r' W( c% I  //uint32_t timeout;& Z: h/ t( c. {) {
  uint32_t flags;
6 J" N& r5 Q- l* @  uint32_t count;
, _9 K  A' f+ _. K" ?( _9 ~* }4 e  uint32_t index;
; g6 M3 N- v; e3 M1 o. q- z5 \  uint32_t i, n;" @1 r, U: r4 l1 }& O. ~3 F
  //(void)   argument;, m2 G. [$ Y4 I2 e
$ {" L- V6 M6 z7 |7 f
  //timeout = osWaitForever;
& D1 E% Z  f1 i, S  [) y1 k& V& L; t# h6 ^- i6 H  `
  //for (;;) {0 u% a! W/ L% I9 |; B( V
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);2 G0 y/ K% O1 W/ |; e
                if((SWO_EventFlags & 0x01)==0)return 0;
( f0 J( N/ ^5 j7 ?4 q         0 r: }0 K2 l& W* Y& I% w
                flags = SWO_EventFlags;
4 @6 W, x& g8 x: y                SWO_EventFlags = 0U;
, X9 s! G9 L: s5 b8 R4 C2 s. w    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
" o2 F" h9 u( C1 q: O      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
: v9 m3 D; [; O+ g                        ;+ p. u; Y, t$ K) r' I/ I, n, E
    } else {: P4 {+ z; V, S1 h
      //timeout = osWaitForever;
/ f% V8 s) P6 O+ G: \      flags   = osFlagsErrorTimeout;1 L# w' `1 U7 T- f. `. p: y# V" J
    }
  ~: `" g& e6 T5 ]    if (TransferBusy == 0U) {) G$ v9 T$ n+ b5 D6 o: Z+ X
      count = GetTraceCount();0 d! E- d( r3 x5 e- v  m
      if (count != 0U) {7 Q/ v% k! ^! D/ G( i3 f
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
! _8 L& F2 W5 P7 ^+ c        n = SWO_BUFFER_SIZE - index;
, l. q( s1 c: H/ t        if (count > n) {
! Y  a* h; k4 |+ J          count = n;2 w) N6 F! D; v& M, J- f" j
                                        . W+ f# |& e& l9 P8 I+ s
        }; y6 L5 A/ c  b5 e' |
                                if(count>USB_BLOCK_SIZE)3 ^; _1 O2 r5 @9 U! E, o2 S
                                        count=USB_BLOCK_SIZE;
8 J( B8 x1 j6 u% K2 y/ t        if (flags != osFlagsErrorTimeout) {
( x0 g4 u2 g4 D  _, F% t1 J          i = index & (USB_BLOCK_SIZE - 1U);1 I- k# F  z( n0 }5 n" I% c
          if (i == 0U) {
  I" _/ U/ Z- L: t, f  {# o/ h            count &= ~(USB_BLOCK_SIZE - 1U);
" a" A8 Q* Q; u; h5 W7 C5 Z$ x1 i          } else {
9 Y, N* V& N5 a6 i2 ]8 d2 x, y- ~            n = USB_BLOCK_SIZE - i;
1 x7 V7 {6 K2 C. j5 f            if (count >= n) {" G5 C9 ^. w7 N% t# w' {0 l% G
              count = n;8 e4 J( M4 k; f- t+ I  r' p
            } else {
7 v$ ~$ r7 _% d2 g! Y9 z  {) r0 l              count = 0U;
. P3 V+ ]& ]' s9 D( A: [4 {            }
+ c+ u; O* `8 h$ _7 ?          }
% p( m( a0 H" `8 J9 J$ D# x        }4 `6 J- {8 R  u0 l& ~8 H! X
        if (count != 0U) {8 b: T7 Y+ T0 W/ v5 q; o
          TransferSize = count;
$ D# ?  B6 G2 m! ~          TransferBusy = 1U;. B' Y, X% k5 [! s7 _
          SWO_QueueTransfer(&TraceBuf[index], count);5 m7 i" R+ k. `# ]4 B
        }" E* H* w4 o; k
      }, R2 t1 y1 |2 X, u
    }  d1 w& X& P0 f
  //}6 T9 |* j& w  E' M; |( W' q
                return 0;
' l" b! }1 n5 w0 g5 B- P% n# N/ `}* N* d" h- ]: g& M
利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
9 K; }, Q6 l$ ~2 N8 X#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).2 ?" L% l: }- t0 \) ^' ~
static volatile uint32_t SWO_EventFlags=0;) B8 d& W0 J, f
static volatile uint32_t timeout=osWaitForever;* w% |' J3 ?0 p  G' i
static volatile uint32_t timeWait;
* O; Z  }7 P3 b* d( Z函数改为这样
2 v, }5 z) u, g; u/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
$ u! I5 G7 j: d; D  j: G( A  //uint32_t timeout;: _1 `1 N. p$ O
  uint32_t flags;' ~' C) L+ z1 K- h& @) O! a
  uint32_t count;: @5 P. X' g/ K! C9 W9 J! i
  uint32_t index;& Y* _' \0 w# X% x* D
  uint32_t i, n;
+ {- p; T1 t# q& Z" F- O  //(void)   argument;
' Q$ q( x, B% M6 ]% N& b/ ^; A$ V) j: J# v( r
  //timeout = osWaitForever;
" Q: H0 \4 F1 |0 D1 N7 w7 |& j9 z
  //for (;;) {* D6 m7 I+ {6 Z. y8 V/ a2 f
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);2 ]8 c& e) I- g$ w, J! J; S6 G" @" Y
                if((SWO_EventFlags & 0x01)==0)6 E3 j0 e* M# t) c% J/ f4 u' l2 O8 W
                {
& @; D5 P# q6 A6 v                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
, n" l' a6 t( L/ p0 |0 n                        return 0;4 F* r, y0 \5 p* C/ x0 C
                        
8 S9 R" u2 s: d* C$ N  K( G1 D                }# \6 L6 g- Z" M5 q% S! e
         3 H/ n8 E9 C( ~9 b1 V8 O
                flags = SWO_EventFlags;4 o7 ?, k6 q- d) k+ V
                SWO_EventFlags = 0U;
/ r; \7 `& i6 ]* a, O    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
: U- f' F, C( Y" U5 F" _' G2 z      timeout = SWO_STREAM_TIMEOUT;9 C1 Q- d0 J( Y1 Y- B
      timeWait=DWT->CYCCNT;/ m# y, u" a5 B8 D
    } else {8 F4 p& x8 H+ E6 l$ o
      timeout = osWaitForever;* i8 O; x) q3 x+ ]6 i8 m2 V
      flags   = osFlagsErrorTimeout;0 s, D. I' v; {" X8 a; K" V0 N- O
    }
% m% C% g6 c2 c% C5 T8 I0 m    if (TransferBusy == 0U) {
  T6 Y2 ]+ ^  H9 h6 `# g' B" C      count = GetTraceCount();
$ ^% Z, d9 D6 I/ e$ j      if (count != 0U) {
7 r8 {0 {' e; k        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);- ?+ h2 p4 [. p; a" g
        n = SWO_BUFFER_SIZE - index;
2 z+ |  l. I- g) c1 B) U        if (count > n) {
7 G4 v/ g) \- i          count = n;4 v# W9 L3 x, {
                                        : u9 p; l  u' I$ n. M
        }! H2 c+ m1 C; z8 K
                                if(count>USB_BLOCK_SIZE)
/ M4 s# F6 f- i3 |: c                                        count=USB_BLOCK_SIZE;, k7 B# r0 P, v5 i/ Q4 g* M
        if (flags != osFlagsErrorTimeout) {+ Y2 m' [# _1 F7 c2 V/ v6 w: s
          i = index & (USB_BLOCK_SIZE - 1U);
( J" u, c; r+ l& v% X          if (i == 0U) {! r9 Z( U; Y1 C. }0 K% x
            count &= ~(USB_BLOCK_SIZE - 1U);
' V1 C/ i2 z/ N$ H! L$ t6 v( @' \" p5 L, B          } else {
. G) @" ?9 _/ i6 _' y1 Z4 }5 |            n = USB_BLOCK_SIZE - i;
4 p% T. A. R- N5 C% \% m0 E! P+ O            if (count >= n) {
6 T& x4 e2 m" M* M' t* y0 p! P" K              count = n;
* V5 |5 U- M( I: ~* z            } else {) U+ Z4 C4 o; q9 \  Q
              count = 0U;- p) [: F0 M4 `2 @4 r3 o2 j
            }9 X/ C; L* S' p/ G
          }
7 N  m9 f/ t5 ~2 F- U        }/ S2 F* Z5 O' U
        if (count != 0U) {
7 t) p! a4 r; C1 k          TransferSize = count;3 f4 x9 e; F/ q* K; X/ Y  `
          TransferBusy = 1U;
/ B9 }3 W- j# U& a8 k          SWO_QueueTransfer(&TraceBuf[index], count);1 W* j7 e8 D# m2 a5 H+ b
        }
4 K; l/ T% v% z% V- B7 A5 D! ?      }
) O' O2 q  i; E  x# p    }
. J7 |- m+ l' }4 m& _  //}  U2 V1 g; I/ f- t  ~$ `* l
                return 0;
9 |! d) ]4 u8 M2 {' C}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了- Q; _( u- y' X# v* q

) M+ D1 ?& i& Z# w  m/ jCDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率! u5 N: T4 t2 h& {( `( Q5 s
" a) g) O; i. z. N- ^. R) P" i

- i9 A" `$ F0 V6 V2 [5 J; B  Rint main(void)
+ Y0 c; K+ S; [9 U{& J% s$ C/ b$ n! Z% ^  j  M( r
  DWT_Init();
2 [3 i2 V6 |' c7 q: V( a) u        DAP_Setup();1 p; K& j2 B5 x6 D
  USB_Interrupts_Config();
1 I' {) R0 q% c& W0 r' b  Set_USBClock();6 ?* f4 y+ P$ U. d6 l' U- Q/ |
  USB_Init();
+ M, n* \( C: x  r" v0 {9 M; P& y2 o        //TIM3_Init(35999,0);9 x4 s+ y3 W1 Y9 C
        //TIM_Cmd(TIM3,ENABLE);3 D3 n  V! n+ S  k8 A+ S& q
        
. g' e/ l# w: @9 E4 g) H# {5 M& \        
$ n2 F; ]9 g) ]! N3 h# t/ F  while (1)
2 U- |3 J( }( C2 T# h6 t* Q  {3 ^' T% P% K4 ]5 Z/ t: k5 i/ n
                DAP_Thread();
$ V8 R2 r# o* b6 Q0 `2 q# k; w                #if (SWO_STREAM != 0)
) u. |: \& I( u4 b: K                SWO_Thread();' m, R( y! s/ i9 v8 b
                #endif! t5 X9 [% J' l% L+ \- {
  }# z/ X  {# f% W, E
}
5 A/ D% z: d$ O
2 ~3 p% f" P" p. a. h# l. @. s对于DAP_config.h的IO配置我是这样弄的  W. \1 ^2 G) v2 |
///@}# {& u% f$ B0 D
// Debug Port I/O Pins
3 G/ n, X% b1 r; V/ \" Z
1 |* l  M) P! B. {// SWCLK/TCK Pin                GPIOA[6]
8 \: L9 i! L. D  f7 N#define SWCLK_TCK_OUT                       *( uint32_t*)0x422101982 H) c0 B$ L. i9 ^# `# g
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118, x7 j& p2 G  W+ n: K

3 j- _6 G- w- c0 A' w: A1 M+ L// SWDIO/TMS Pin                GPIOA[7]9 S( }/ X& {  q5 |( x5 ~$ H1 y
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C- I5 b( S: d0 h
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C# }* W3 ^7 v, g8 D; b9 g1 K  s
% J3 N) p/ _% c3 l% F
// SWDIO Output Enable Pin      GPIOA[7]
1 x3 ?5 a" H( }; c) ~0 }4 g2 o#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \7 N  R) i, D. b8 z! A$ T3 o
                                                                                                                                *(uint32_t*)0x42210070 = 1; \
3 Z( Y/ U  a. x. s                                                                                                                                *(uint32_t*)0x42210074 = 1; \
* h! |# V' \9 O                                                                                                                                *(uint32_t*)0x42210078 = 0; \- O, |2 L9 a" V# l. i7 \
                                                                                                                                *(uint32_t*)0x4221007C = 0;}2 Y/ t2 H0 m; V& y+ v
/ H3 T5 N. b! R. }* c/ I" y
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
; ^! `+ X% v! i4 p4 m                                                                                                                                *(uint32_t*)0x42210070 = 0; \
+ y; i2 G* U/ w4 F( c                                                                                                                                *(uint32_t*)0x42210074 = 0; \
7 L, Q+ r8 Q1 d                                                                                                                                *(uint32_t*)0x42210078 = 0; \
4 X* Q& Z0 r8 X' h* K# g; B                                                                                                                                *(uint32_t*)0x4221007C = 1; }
4 s: h, Z$ ~' i0 K7 t
5 w7 Y' X& T0 r& }// TDI Pin                      GPIOA[8]9 L' p7 O  _/ \, P
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
, Q1 Q5 @4 Q" ?* @0 B' G#define TDI_IN                                     *(volatile uint32_t*)0x42210120& E( H" }7 H/ ]. ?# @4 I% v& C6 \3 L) f- {8 Y

: R% G8 f! r6 m// TDO Pin                      GPIOA[10]
9 _0 R* p9 [9 q) z#define TDO_OUT                                    *(volatile uint32_t*)0x422101A81 x6 h/ g" c0 L' b/ G" D5 C" j" F4 }
#define TDO_IN                                     *(volatile uint32_t*)0x42210128
  [6 i' O  a( ]( `/ U! T3 r. }- l4 [; j+ y, `3 G1 a
// nTRST Pin                    GPIOB[3]% b- \' I9 p, {& v: t
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C3 s7 f. \  c5 B4 {0 t# p
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C5 f; P1 @- G- ]$ \- R1 O

% }2 l$ \. {* K7 T) x7 W/ w/ u// nRESET Pin                   GPIOB[4]+ x+ E: F6 o' B; ~  |3 i, D# o& a
#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190" V8 y( h( P8 E7 @! B: y
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110- K1 [* z% a( H, i. h

/ q% U3 \6 J- B( P// nRESET Output Enable Pin     GPIOB[4]! {/ x( v+ a) i4 ?- M
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
4 f* U: V) P) W- T1 m                                                                                                                                *(uint32_t*)0x42218040 = 1; \! P1 D) d0 q+ w4 H* T6 Q
                                                                                                                                *(uint32_t*)0x42218044 = 1; \
' i( S7 I( {3 s                                                                                                                                *(uint32_t*)0x42218048 = 0; \! P* w0 o; P9 m7 y$ K
                                                                                                                                *(uint32_t*)0x4221804C = 0; } 9 ]% r- N  a. w: I7 y/ A; c9 l/ O" q
; n& a& f3 B' Q, u
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \4 h; x0 A9 t. ^' R% ]" L- B, ^: Y
                                                                                                                                *(uint32_t*)0x42218040 = 0; \
. y  u6 p3 Q8 [0 L                                                                                                                                *(uint32_t*)0x42218044 = 0; \: {  e6 L2 V# }3 h  g9 s
                                                                                                                                *(uint32_t*)0x42218048 = 0;\" t, m" z+ _3 V
                                                                                                                                *(uint32_t*)0x4221804C = 1; }; C$ _$ v8 x( D  [1 p3 F

: c+ g$ w- o: G* k5 {5 U4 e/ |2 p7 t: J. c* f. H
// Debug Unit LEDs, X! Y+ T* q3 e0 N

3 V4 r6 p# j9 i! F0 K8 e/ o// Connected LED                GPIOC[13]( P: F4 u* P: N, S# I8 [
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B40 q3 N$ S; Q' [( S4 n/ X
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
6 K! s5 g4 T6 I% K' Y, b+ Z" T, ]5 U9 T4 Y( c
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \9 a7 W8 E+ K7 {4 I% [
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \, H. f5 i# h- _2 A
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \
3 \1 _( G' m# U5 ?- f6 W                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
+ C0 w& v, {( l- ^                                                                                                                                *(uint32_t*)0x422200DC = 1; }" @9 \/ Q4 ?4 @& {7 O6 K% [
// Target Running LED           Not available4 M" P+ d: e2 d! T: l. x

' L: o! O! J4 ]* N: E1 y// SWCLK/TCK I/O pin -------------------------------------/ F- V6 Y5 X" V+ R

- a; w  P4 X1 M: D1 y% e/** SWCLK/TCK I/O pin: Get Input.5 |% F$ r0 K: R& b8 `
\return Current status of the SWCLK/TCK DAP hardware I/O pin.! S% |- U9 w  x+ ~0 |) \
*/
) Y* U1 W1 y, w8 u- w& l__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
6 K: p* {+ b6 @" c  return (SWCLK_TCK_IN);
. I* q8 y: U! G2 }! Q) I6 H9 n}% k( u: _3 P( h5 o* a
: h0 G% o/ j/ q
/** SWCLK/TCK I/O pin: Set Output to High.- B/ l- x, S, e, g2 ~  m" J
Set the SWCLK/TCK DAP hardware I/O pin to high level.
9 ^9 {+ J" Z8 b( e*/2 I( e. }7 K2 N" k( S" N6 B
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {) q5 i% p/ c3 g7 k' a
  SWCLK_TCK_OUT = 1;
" `$ |# m/ B+ ~. r, u+ |}
  A- O# s7 x4 U/ }: r) j8 u& h3 r1 G; v& r
/** SWCLK/TCK I/O pin: Set Output to Low.) W  ~0 I# S# A! {: N' y* h
Set the SWCLK/TCK DAP hardware I/O pin to low level.
) F7 d* v1 T* Y* D: I  s* }. i*/- q. i1 s- H5 l1 O+ m# @
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {+ Y5 A6 f' b, X6 F
  SWCLK_TCK_OUT = 0;5 N9 r1 B5 }5 @5 w1 U0 q. y
}
( _+ K8 w1 j8 `" P2 m' X* M0 t% `# X9 d7 w; M* O; d9 P
" j+ B! Y) B. B- k% G0 l8 V  Z
// SWDIO/TMS Pin I/O --------------------------------------3 L3 z4 C. T1 R1 E* v+ |' I8 f# n/ K
0 t* a: r6 A! \! n, ^' L
/** SWDIO/TMS I/O pin: Get Input.0 h5 l5 g6 g1 h  J* f! }; T
\return Current status of the SWDIO/TMS DAP hardware I/O pin.3 z1 ]  r$ L1 S3 D8 Z
*/
7 @- J/ w9 ^- K4 E; ~! D( v__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
+ T6 q) j6 P* Q$ E& t- [0 h; b- F8 a  return (SWDIO_TMS_IN);0 ], S1 }7 H# R
}
7 N/ {+ Q: P1 M* T! E( C9 h8 ]8 a3 {" u/ V7 l% w
/** SWDIO/TMS I/O pin: Set Output to High.
; b3 U9 M8 O2 t0 b9 j, i; W- ASet the SWDIO/TMS DAP hardware I/O pin to high level.
: |3 u7 y( ~4 x( d( @*/: j; p% y7 ~! e/ u/ N: X* Q
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {5 t3 X  B. L/ @$ u* M# U
  SWDIO_TMS_OUT = 1;
! s9 \9 k% U0 S# B}  P+ `( K7 e& Q  x* z

* W/ g! u$ G2 A% u, E/** SWDIO/TMS I/O pin: Set Output to Low.
! B6 @( G  |& C3 ^Set the SWDIO/TMS DAP hardware I/O pin to low level.$ P9 I/ M! F3 G" B/ Q1 T. n
*/4 o3 f, C* o  ~8 O, U1 Q: i3 N3 k
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {( q. G  S1 S. K/ r3 O6 d
  SWDIO_TMS_OUT = 0;
' l5 h+ v9 r; k! L+ @1 \}- J9 f% I1 C' W' u
$ }9 d" a! h! P* ]5 Y' H/ r
/** SWDIO I/O pin: Get Input (used in SWD mode only).
9 l* {# x+ n. F0 f+ f\return Current status of the SWDIO DAP hardware I/O pin., S  d1 e0 @! g, j# w0 `5 r8 R
*/* e5 m" i, N' R" U, K$ r
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {* z4 t7 \- L8 h2 ^
  return (SWDIO_TMS_IN);+ S2 ]. l% \0 H7 T$ z# o/ B
}
3 k2 @2 `2 B; }2 Y9 Y9 i! v# P, E3 Z. L% C" B  Y* g3 ]
/** SWDIO I/O pin: Set Output (used in SWD mode only).6 W- D. t0 M) o% i2 T
\param bit Output value for the SWDIO DAP hardware I/O pin.
9 _) p! k$ ^. a# L8 X, G*/
8 |9 H( I2 P1 _( _$ X3 e__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {! v8 F: J0 \* R" ~7 U
  SWDIO_TMS_OUT = bit;
- C9 f! X* _1 P}: l/ X" c" L9 w+ i3 N+ n; m* |

3 T8 E; J$ V  C* x, o' m/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).9 h6 ]: w4 w- Z9 G. F5 A% Y! S9 J4 n
Configure the SWDIO DAP hardware I/O pin to output mode. This function is3 n! h, M# d5 v/ i2 f4 |  C
called prior \ref PIN_SWDIO_OUT function calls.
/ f% c( A6 ?  p9 b  S! S, v*/7 I6 r9 b+ j# l' _+ I
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
$ R! o9 R- C$ q  SWDIO_Output();
8 `( K1 T! Y, \; L, w" ~8 O}
) c4 b, ]3 V% I" y0 e7 Z( O2 p) }5 \+ ^0 o6 o* |
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).9 Q4 h" a" B- O/ x+ C' c* {; c
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
2 Q1 [* L1 G0 C1 C7 R- a) Mcalled prior \ref PIN_SWDIO_IN function calls.
8 ^! ~; t3 E, u9 S2 T8 b1 `0 }*/. B% V/ n* c6 R
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {( @8 N) f, l" c7 v
  SWDIO_Input();  B2 s  f9 g. C+ G' _' q. Y
}
0 E" S# N; Y- ~- }
5 R" I- P/ ?3 \" I+ K; }3 |# H楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的! h% ?( W6 i, T9 b
即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
& @6 x8 b' U- A  m- k( p
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版