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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。( X, w) o4 a- D: u6 y
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50- D# w2 B0 o' a
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

( `0 m$ m& J8 e( w! y9 ]我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。+ L4 T: A+ z# y1 l: n/ w7 ~, W9 l: I

+ x: l/ i* Y' h. H/ w( t软件复位是另外一种情况,需要向目标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
1 h" N; J+ f( V1 g0 ~可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
7 h7 d( b, m/ Z$ b& r$ o
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。) l8 i, k# l% o/ m& u5 a
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。& T/ e; f: {, m
7 T! u/ d, b& ~$ p
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
1 ]/ b4 ]5 f# R2 c1 }6 `或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
4 x$ ~* n3 T. B9 \! M
( n0 W: W/ A% t+ g1 b: Z3 w
8 e9 Y- q0 K4 B( a8 w
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?( v; A2 A9 z) A' S
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
8 G, U) L0 h* T% ^% M5 M$ J1 R8 N: z
起点VS 回答时间:2022-8-12 09:23:24
正需要,这是好东西
KEVIN.Z 回答时间:2023-9-7 22:41:22
我也自己用ST官方标准库STM32_USB-FS-Device_Lib_V4.1.0移植了DAP V2.11版本的,即CMSIS 5.9.0里带的DAP,芯片型号用的STM32F103C8T6核心小板子,实际上我还有一块板子装上了APM32F103CBT6的,程序能通用,没跑RTX系统,轮询执行
- a. A& @2 r  C2 o- v- J2 C/ ?/**
/ l/ i! T( E; V+ g# ]* {  ******************************************************************************
' l% c. w, P% U  * @file    usb_endp.c
. t6 N0 U# i( i9 B  * @author  MCD Application Team7 p. z- |5 @0 C9 p  O* o; N
  * @version V4.1.0
/ Y8 N4 z8 ~$ `# F  S, E1 ?8 d  * @date    26-May-2017& Y! V: X: v2 v! ^* f* W8 @; O
  * @brief   Endpoint routines
0 m" i' K' t0 w' b- C# B# @7 r  ******************************************************************************! w* }" P5 V3 P6 `- M: [
  * @attention/ O+ k3 N' [9 k+ E; n2 |  W6 \
  *0 ^/ `" X; P& h: V
  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
9 s) y7 Q8 f) L  *
# s6 |; c1 {. Y% n( M" H  * Redistribution and use in source and binary forms, with or without modification,1 m- o$ Y" _( |
  * are permitted provided that the following conditions are met:
* {& B$ _: _6 ~$ O9 f4 a$ e: O  *   1. Redistributions of source code must retain the above copyright notice,8 m9 o2 V1 E" A. x
  *      this list of conditions and the following disclaimer." v+ Y, i0 t" d! Z. P- e! c. e+ V4 Q
  *   2. Redistributions in binary form must reproduce the above copyright notice,+ S/ _4 e! l: ~) W2 n7 ]
  *      this list of conditions and the following disclaimer in the documentation
+ B2 ]8 C2 H* l. j' A# J1 b  *      and/or other materials provided with the distribution.
7 R7 F: h! n+ I8 ^9 w3 _+ K  *   3. Neither the name of STMicroelectronics nor the names of its contributors
! }8 j8 u1 p- C* N9 ^5 P" G: l  *      may be used to endorse or promote products derived from this software3 s- T+ i; w5 G" q! E
  *      without specific prior written permission.
- l+ J8 }' c, G" L* V: j  *
' {5 l" X& i8 L3 S. w  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
" q2 g7 q( x. v8 A/ y5 p/ t  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE' Y( \8 M! t& |* X2 }
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* J- V6 J& M" _5 P
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
4 u1 e" g7 Z. g' b3 X2 n( j4 D& y2 n  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
. J) h5 u0 X5 z6 Y* s& s" b  t  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR  n5 b6 ?5 F2 w  S% a: v  W; }( D
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER" F) L3 Q* P' s& ]
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,0 E) [% e* O) ^+ j8 i% p6 @
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE" B. Z( K% P& C: a
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- v; \  |. `3 M# I5 s  *6 |3 G2 g0 l' o
  ******************************************************************************6 @' V* E8 S1 `7 R+ D
  */
1 @6 g! ?4 L' P! G$ t5 x0 o" G. R. [: l! ?: P
+ V. o! ^# s- C! e" u
/* Includes ------------------------------------------------------------------*/) d3 R1 j: d# K' A
#include "hw_config.h"
) P" d7 Q. F: h8 n+ x2 j; m#include "usb_lib.h"
9 U" M0 f9 r5 s5 m* F  ]' P/ j9 b#include "usb_istr.h"5 |; p! N0 O6 \: A4 a5 G0 {
#include "stepper.h"1 S5 F4 O# O9 {" G5 Z
#include "string.h"3 k' }+ n9 b/ ^3 B6 P; G
& u' H# t, c: F. D# x" F
#include "DAP_config.h"6 Y, D3 s; t% F8 k# }3 v
#include "DAP.h"  T8 t. e5 o3 t: \3 S8 l  Z2 m5 B: p

/ k% p5 i, r8 b2 r. F/ R6 N( I& H( _+ l9 ~
/* Private typedef -----------------------------------------------------------*/
' \; V! s) c& x  r. k% `/* Private define ------------------------------------------------------------*/( d6 T; |. H0 Y- j, {
/* Private macro -------------------------------------------------------------*/  P, t$ W/ I* d
/* Private variables ---------------------------------------------------------*/% Z, `9 g8 U9 o: u" S
static volatile uint16_t USB_RequestIndexI;     // Request  Index In8 @- \* z: y: w3 b: v4 X" B
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
! D3 f' T: e1 Y3 G: D7 V. n7 Y- Jstatic volatile uint16_t USB_RequestCountI;     // Request  Count In4 R) d4 f7 f/ C( i/ x1 k/ Y
static volatile uint16_t USB_RequestCountO;     // Request  Count Out
+ p1 F) g1 b& I0 Nstatic volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag/ D8 v* D  Q* B6 b9 |1 v7 L  m
3 {3 C, F5 K2 Y. J$ s
static volatile uint16_t USB_ResponseIndexI;    // Response Index In
( X. J0 G, h: X2 y5 N$ Hstatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out5 E$ T0 o$ k# g: K' O+ r
static volatile uint16_t USB_ResponseCountI;    // Response Count In
+ n8 `: x7 W; C) r9 Y8 _, tstatic volatile uint16_t USB_ResponseCountO;    // Response Count Out
( Y2 _) ?+ {2 H, o; w% V, ustatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag; r2 P4 V: x7 o4 P) e$ F
static volatile uint32_t USB_EventFlags;
5 O/ t8 S: k9 [% y5 f9 X
7 a& W0 E% r( `2 k8 m" }static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
3 v/ \0 M# ~, M3 l# estatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer' q" w7 g& l" W. h" V& p
static uint16_t USB_RespSize[DAP_PACKET_COUNT];% S  H: V9 n/ o+ n4 S2 Y
% _) Z* l% ^( h" y% }% R" s
/* Private function prototypes -----------------------------------------------*/9 I! A/ v; \. ?# f* p% k
/* Private functions ---------------------------------------------------------*/# f  b6 @1 n  ?, S
/*******************************************************************************: t0 [4 B9 F( I
* Function Name  : EP1_OUT_Callback.0 r* j3 S/ j9 j( h3 V- R. @
* Description    : EP1 OUT Callback Routine.
5 q/ b. ^% L& H! j* Input          : None.. [; q" B) D8 Q! [; x* ]: u. f$ A
* Output         : None.3 t0 ~- }8 n" N6 d. Y9 {
* Return         : None.( [6 D. z1 G) N
*******************************************************************************/6 G( j* a, e; c- E9 \0 f/ `+ W$ M
void EP1_OUT_Callback(void)
! s4 E5 i( V8 M. u{
5 z2 D  E. \) h        uint16_t n;
: p+ Y& S5 _6 O" O) W( _) }7 y7 P5 Y9 n# o$ m" E$ Q$ m* {" O
        n = GetEPRxCount(ENDP1);; P6 }- X; \8 K* `
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
& `' {8 N( D3 d; Z- G# g5 ^$ s        if(n !=0){4 d8 C6 P( }6 R, o* l
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
; k: n& ?& j. u( R                        DAP_TransferAbort = 1U;
6 _/ }: D9 C% b$ R& k                } else {$ Y) J! d$ N" N8 R2 O& y0 i% T
                        USB_RequestIndexI++;) G4 j$ G& j) s
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
7 m5 f+ C; E" z7 M$ f                                USB_RequestIndexI = 0U;1 n* c* M) \5 f" q, R
      }
* B7 w" g0 ]9 P% D/ O      USB_RequestCountI++;
$ S/ ?" i  J& X' [& z7 g        USB_EventFlags = 0x01;- T6 N+ H. c6 T4 a+ S, V# p, L9 Z0 U
    }7 j9 Z* s9 Q6 u  V1 v
        }        
; M3 S1 l' S* Z- T        // Start reception of next request packet
- R* D3 ~. l/ R% ~        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {8 F4 Q4 a9 |' a0 V- r
                SetEPRxStatus(ENDP1, EP_RX_VALID);; t' {0 W4 s+ ~
        } else {' D6 W  _7 R: V7 d. b/ I" P
                USB_RequestIdle = 1U;
) ]( b4 Z) i  P! O1 e        }                        ! R0 _' E1 u' T, m
}# [+ v% v3 B" E% F7 d6 H
( J9 ^8 Y( {$ b" R+ Z
/*******************************************************************************
3 D2 F) z, U) t7 U% c- v# y7 O* Function Name  : EP2_OUT_Callback.6 \6 g2 _4 p! m' b( x: v+ e: O) R
* Description    : EP2 OUT Callback Routine.) b. T' K7 I; M( ]$ }& w
* Input          : None.
  M) P9 u# M) ?* Output         : None.
" U# }( E1 }+ s4 l+ d# P: m* Return         : None.
0 |$ t. U1 k! E8 y*******************************************************************************/! H" f. N7 R; c) {& J
static volatile uint32_t TX_n;
- G3 d8 e8 ~' q: ustatic uint8_t *pbuf;
# F" R7 v- S1 X9 j! m/ ]void EP2_IN_Callback(void)
  E- `4 n* O1 j4 s( @{$ @- B# R# T8 V9 C
        uint32_t a;
. f7 d& l0 L- j7 \        if(TX_n>0){( c& G- a. K$ [6 r2 Y1 f
                pbuf+=64;( b4 Y; D; p6 X' }
                if(TX_n>64){! S' ]/ v. [/ ]  s
                        a=64;7 \! X. J2 R; f* {# F3 `: r& C
                        TX_n-=64;8 H8 y5 M& z7 F- M8 X
                        
/ z2 P1 i8 E7 v4 Z; o                }else{
2 l% }+ z% D3 [3 r                        a=TX_n;
; \4 i: s! i$ {7 s                        TX_n=0;& m) p! w. ?! L! x1 ?
                }7 E7 A1 q& W1 }( F6 }3 a3 |% d
                6 K, R, Z8 B+ A1 H0 o) o8 T2 B
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
3 O, H( h$ E# n( e! ]) P        SetEPTxCount(ENDP2,a);
% Q+ G$ H$ }0 \5 F( _. l& |                - O, W: D5 S7 S
        SetEPTxValid(ENDP2);
6 o' t% u1 i) B        }else{
0 G6 ^. d( v8 W9 x" V1 I. k                #if (SWO_STREAM != 0)
7 l2 n. F& C1 }# _9 d) p$ ?& x                SWO_TransferComplete();0 I- _7 A( Q8 s  V+ z
                #endif$ |5 L8 f' A: U* k* G
        }9 Q8 A# ^, t4 J- U9 P( z
}
% l: g/ W" v0 }( Y/ w0 R4 C/ _
* u$ ?( I! r2 B* y/*******************************************************************************6 J3 i) t* c+ R" F7 g! I
* Function Name  : EP1_IN_Callback.
  f# _7 u* y( K$ [1 g7 Y* Description    : EP1 IN Callback Routine." m% z- N( e; W( m
* Input          : None.! @2 B9 E. C+ R
* Output         : None.1 Y* d$ J' ^: A. [
* Return         : None.+ ~& W7 F# u5 {
*******************************************************************************/
" H- h% |* F9 R& [( O1 Mvoid EP1_IN_Callback(void)
1 Y! L7 B, p; c; v6 B4 ~8 j{
& r& Z* [  ^$ d3 w    if (USB_ResponseCountI != USB_ResponseCountO) {
6 A$ n' J. \; V& ?0 k8 N/ ]" C$ C      // Load data from response buffer to be sent back
4 N$ G& U, s9 ?7 C8 T9 R$ K  U                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);  \7 G1 H- E4 f& |
                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);- A6 J( m8 g2 ^' D
                        SetEPTxValid(ENDP1);                        % X; f: h0 K" @* ?+ p8 W
      USB_ResponseIndexO++;& I- d+ w. K4 n4 [! k. J
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {* [% d6 |; Z; W& Q" G
        USB_ResponseIndexO = 0U;
! x2 J7 E" T/ e3 s3 B& V0 ]      }; }, W* A6 X$ ~$ s
      USB_ResponseCountO++;1 W; `! G: |+ X, G/ o: x; J3 X8 D
    } else {# t/ u& g0 h0 f5 m
      USB_ResponseIdle = 1U;5 f' Q- A1 S9 u3 v  R) k
    }  
. u6 d) L5 b. @  h1 O" b. u5 \}5 g3 `0 A& \6 v% C4 q

0 w, B0 u; E+ a& N& y- q; R// Called during USBD_Initialize to initialize the USB HID class instance.
& d# b, ^3 g6 ?: `* _0 F$ O5 nvoid DAP_FIFO_Init(void), O" t- B/ c6 Y" A% ?" S+ m
{
8 M! ]* x; u. j, \    // Initialize variables; n' j- d& f# K# {: T  k+ U1 E
    USB_RequestIndexI  = 0U;
9 r  ]1 E% _$ u$ x# A7 Z    USB_RequestIndexO  = 0U;6 R. r$ @' j9 O; \! `
    USB_RequestCountI  = 0U;
7 D9 w0 Y1 z6 B$ }  s, \! `( F    USB_RequestCountO  = 0U;( a. K( m) u9 p3 Y
    USB_ResponseIndexI = 0U;
& q5 L1 a3 k5 U" l5 t2 I0 |    USB_ResponseIndexO = 0U;
+ b+ `0 l) O9 W6 c    USB_ResponseCountI = 0U;& `. Z- `1 }  O( D
    USB_ResponseCountO = 0U;6 k5 K6 ?# ^2 Z, L, Y
    USB_ResponseIdle   = 1U;  @% l0 \' n5 t) R
    USB_EventFlags     = 0U;
9 U* \/ n( w& M% |}) ~: Z' \" v* f. F2 S" l, ]

1 W$ r/ e" g7 l. @( quint8_t DAP_Thread (void) {
- ?1 E3 D9 V' M$ h) a) k  uint32_t flags;0 I  }$ H" B0 F4 n5 T
  uint32_t n;
  P, w* U, [3 F3 O4 F  E( z5 g+ B' ]# M+ v7 D
  //for (;;) {
& F" \. b3 b* L5 F3 r  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
8 u; o# W, [% T# ]3 c; K/ S9 J, m! R                if((USB_EventFlags & 0x81) == 0)
" }; @. }7 U2 _- \                {' k8 b* u- g) u9 T6 v6 K: w
                        return 0;- c* u' n! e( W) s& q
                }# ]# _$ n; P( v/ n, s& y
                USB_EventFlags &= (~0X81);
+ M5 P$ a* q+ j$ y4 v8 a2 E/ ]                * Q) R. ~0 Y4 i" Z9 g5 f
                                        ! |4 }9 v6 d3 P& F
    // Process pending requests& b0 f$ m) G, `3 r: B
    while (USB_RequestCountI != USB_RequestCountO) {0 u# z) m* v& E$ j% C$ p
                //if (USB_RequestCountI != USB_RequestCountO) {
8 @9 N/ ], O7 {3 u/ j3 [      // Handle Queue Commands* Y6 a$ D% a4 w- {5 e
      n = USB_RequestIndexO;
8 _  W& d0 o8 `: j      while (USB_Request[n][0] == ID_DAP_QueueCommands) {
$ u7 V; s0 `4 j: I9 x: K                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {0 d9 m. S8 q" l$ S
        USB_Request[n][0] = ID_DAP_ExecuteCommands;( y3 w+ e, W( x. s+ e: e. I+ d' d, n
        n++;
+ \/ a) d* A0 M9 r$ {; q        if (n == DAP_PACKET_COUNT) {/ F' U5 A' Q# K, j, O/ z
          n = 0U;
/ F; q9 }0 p5 a& V        }
5 S" I! i0 B" j" z, E        if (n == USB_RequestIndexI) {, U1 T% c+ y/ b
          flags = USB_EventFlags;
) p( K% @4 G: H0 `0 a! Y          if (flags & 0x80U) {0 Y) ^0 P5 m: \2 ~7 G
            break;# M  r: {1 v: h, N
          }& h* S1 d9 R$ a2 \6 c1 e; R$ i
        }" z9 b( i& H7 O/ U! G5 o8 _$ r
      }
5 c* H1 i& }' u2 n$ ~# k5 b  S
& x3 C. S) t8 S      // Execute DAP Command (process request and prepare response)
, J8 ]% i& k' I3 Y3 Q      USB_RespSize[USB_ResponseIndexI] =. r+ n' e. T* T" ^
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
% u( E6 n, D! m) z9 y- J4 {, ~
8 d* G) m# Z1 y/ e( U% Y# S7 R9 l; @  U      // Update Request Index and Count
6 k- Y# V$ l$ A      USB_RequestIndexO++;
8 Z: [4 _1 ~6 B/ {; {7 S      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
2 d2 [) P0 N9 V7 I6 t# m) P        USB_RequestIndexO = 0U;
# G, `/ X: I$ U" s      }
. a7 e1 g4 {& n' ^7 S( X- L& V% [      USB_RequestCountO++;
  [$ c( s$ V1 y; n
4 W+ S; p& N2 w5 }      if (USB_RequestIdle) {
$ _. c' `0 V: g/ d        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
7 C  I8 S( {' F: p' C$ E3 F; n* b- l          USB_RequestIdle = 0U;
/ |& T* q# o2 p9 W          SetEPRxStatus(ENDP1, EP_RX_VALID);
' `/ [5 [. a9 y- ]9 M9 ?        }) t# G+ h) E. k0 z/ A$ C; J
      }$ M" G2 ?- F1 I0 K+ \
3 Z7 p6 `. F0 O0 [" I. O( N
      // Update Response Index and Count
9 @$ W' D) n. }! @- i4 |0 ?      USB_ResponseIndexI++;
, w- `( k4 y4 E      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
, V% X6 P6 l! |" A; q) j0 e        USB_ResponseIndexI = 0U;
- F) j  w& B  ]      }/ O; v4 R. o2 z) T; J4 N# S, b% K
      USB_ResponseCountI++;3 l4 P( q' w! z% _
, N+ Z2 _- c- j8 |! {- q- k& I2 n4 T
      if (USB_ResponseIdle) {
. C. ~+ ?3 D8 ?& o  N; X        if (USB_ResponseCountI != USB_ResponseCountO) {
" l7 x- r/ R3 R  Y% o          // Load data from response buffer to be sent back0 t( ]' Y# T' u& z' m
          n = USB_ResponseIndexO++;+ A- I- |6 k* X7 T7 s4 u" o( r
          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {5 i, \* [' m$ b& X) q1 G, U* ~: `
            USB_ResponseIndexO = 0U;
. t2 B9 y5 L9 j9 _- n1 t! ]! M2 `          }& Q* h- j( E* l6 y5 |6 i1 j0 g
          USB_ResponseCountO++;
3 }5 u, e  |+ B6 T1 v          USB_ResponseIdle = 0U;
5 D/ d; D1 l6 J3 B& a% @, c& ]          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);! X) ?* l1 M% M5 e. T
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
" f' S! z; l( `$ }! n                                        SetEPTxCount(ENDP1,USB_RespSize[n]);. r1 J- o/ I9 a( y( L1 c  t9 S. j
                                        SetEPTxValid(ENDP1);# S1 S( l5 y6 ^" u! V
        }/ ^$ d! m  t$ b5 u% Z- O
      }
5 Z) d7 l0 u4 A+ |/ P    }
3 t- [- M( `/ V0 C; K& d6 H        return 0;% ^7 X# ~7 w/ J6 k9 M7 w
}
# {6 L9 o$ r' I- u
! v' G: V6 p1 {7 v0 m9 F+ m// SWO Data Queue Transfer
5 {6 Q0 j) x( a& r4 p//   buf:    pointer to buffer with data
8 l8 s+ B9 R" y3 Z. h- z//   num:    number of bytes to transfer
+ \! I9 a1 Q/ Q- O0 u3 Z. |! [void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
$ c! k$ o& r, ]2 U; c) M1 G- H( W  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
* G" \! j6 \% n* t, V- l# R! H        uint32_t a;
7 A3 _' |8 x" K' x- Y        ! L3 |& A" n& N- ]. n" {2 s
        if(num>64)
7 b+ R3 o# i6 G- A/ ]( w        {
( v7 t5 Q2 \, R, D) h                a=64;+ S' {6 M4 z+ x3 l" R) W- _
                TX_n=num-64;
6 q0 F% [4 m7 G& e+ f                pbuf=buf;
5 o" h3 E& d& h' }
" N; T7 c: j: @/ F        }else {
$ D$ M$ J" G; _! ~- X& H( K0 ?                a=num;: W0 M6 w, e0 Z9 i
                TX_n=0;
/ K% ^; N' O" z. r( v: }) d+ ]! G        }) D+ D# [+ q: i
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);! g6 s! P1 ^* `  M
        SetEPTxCount(ENDP2,a);
/ }5 {' z# T7 I2 i8 B        SetEPTxValid(ENDP2);
( g' L5 x: @9 @}7 y4 e# }1 Q/ v# o7 x2 y8 ~  z

4 J* C% J* c0 W6 D* l5 p9 X8 D2 B// SWO Data Abort Transfer) J& i5 v9 m' q9 a0 _
void SWO_AbortTransfer (void) {- V* ?4 m$ U$ M  w
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
7 L5 y% o8 v4 j& V( A. A        //SetEPTxStatus(ENDP2, EP_TX_NAK);" D, T  Q+ l. |. O, _& ?" l7 _
        SetEPTxStatus(ENDP2, EP_TX_DIS);$ f% R7 @5 _9 ^& K
        SetEPTxCount(ENDP2,0);2 P, `4 H  j- C6 F' Q
        //TX_n=0;
8 h  u7 P, {7 V  k4 X) }- R; v5 P# S}
$ j2 ~2 ^8 S; s2 v/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/: D. `4 I& s: B  J: @5 h$ [

5 C' `2 E0 N3 [9 G0 H: m移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
: z3 K+ Z$ |$ i3 N0 L; GDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了
1 u6 ?1 P6 Q3 Q( v3 s__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {, W1 J9 C* z: X4 D' A, \& e
  return (DWT->CYCCNT);
$ O0 X( |1 h+ i( m4 _}' k; ~& M2 ?& @6 P* F
: ^. d) X" D  G
void DWT_Init(void)# p0 q5 D! i4 v4 O, c
{( H! v) w! r, ?1 U
    /* 使能DWT外设 */
0 K$ s) e* J# Q- D    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
% G6 H$ G6 D/ A, y2 h3 Y$ ]. X, O) v* K  S/ P5 z
    /* DWT CYCCNT寄存器计数清0 */& g9 @. E$ J* J3 `
    DWT->CYCCNT = (uint32_t)0u;
1 y: t; b" I) s- E2 X" @. a4 R5 S" u* o* X, z
    /* 使能Cortex-M DWT CYCCNT寄存器 */
% x8 T5 f$ p' A" ]' R' A" L    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;* o4 S7 E( I% M. s
}( `. c6 v3 E. O. n  z2 O/ ~
        9 {( o! W; ]! S+ L" Q! [  M! m
4 W; M( n7 m0 N) o2 }! q
然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
# {5 O" i: B# ?) B4 A% [; x5 D- a' L* ^, }  Y0 O3 _
然后改为使用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不香么?
3 G9 d: k7 n4 X, t声明这个变量static volatile uint32_t SWO_EventFlags=0;
7 ?; r. d- V. G( G在SWO里每一处调用osThreadFlagsSet的地方都改为如:2 g/ j3 N; `/ B! R& _
//osThreadFlagsSet(SWO_ThreadId, 1U);
0 A7 N( _  n% T& A( A7 lSWO_EventFlags = 1U;
4 ?0 a+ L, F& g; W# ]  Q6 m
* }$ g0 }/ [1 @* u1 `( ?
3 J/ H6 j( {/ m- s// SWO Thread
2 _! o6 B1 N; [$ O7 K/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {- j$ r0 r1 Q" J% o3 Z( @! _5 v9 q
  //uint32_t timeout;
% `- b# N6 e# P  q  uint32_t flags;
# C8 _/ B! y3 @& S. ?  uint32_t count;
2 |# ^5 Z6 @: `* _  uint32_t index;
; t: C/ Y4 e' d( a( h* e  uint32_t i, n;" l7 j* A  }2 N1 \% a
  //(void)   argument;1 c5 n+ C  X4 U$ [4 M7 Z% h

! ]; K) f2 x  d7 ^+ E* A  //timeout = osWaitForever;
6 j4 F; G. `  c) l6 j& ~3 P1 ~( }
8 q7 g+ ^, [, f/ O  //for (;;) {! R) J4 B, V: w$ U0 B5 K- R
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
3 Y" j' a$ g& g& z- G3 h* d8 [* A: x                if((SWO_EventFlags & 0x01)==0)return 0;
3 Y! E# d; Z/ \/ o. d) y+ e5 t  i         8 f& ~. c2 s- q) {% R8 P1 l
                flags = SWO_EventFlags;
) N' V& \' _+ R" C* Z                SWO_EventFlags = 0U;
3 V2 S, B! K7 _5 `% J  K' M    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {% k  Z; p- K# p: t9 S6 u1 A
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子* [3 P! f( c. X( h7 L
                        ;, ?/ F7 I& k! Q; \; z% P6 C
    } else {+ X3 o8 l- v: F' Q+ S
      //timeout = osWaitForever;- E5 E5 i1 B& V' B, C
      flags   = osFlagsErrorTimeout;
" \, m. L/ r8 N    }
# H, ^0 X- p" L    if (TransferBusy == 0U) {  d" `' x' t2 h( }# \2 V) s
      count = GetTraceCount();5 q: v( ^6 j7 P3 z$ ]% Q
      if (count != 0U) {# r$ I% C3 U1 X; t# H) b: g* Z
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);$ p  R' e* V+ d
        n = SWO_BUFFER_SIZE - index;% X( f& x4 C# _- ~2 P
        if (count > n) {
. Z- |, O2 {' t" \! o          count = n;. {: j& t! `7 U! p% \" K
                                        3 t+ @0 `: [$ p! x% n8 J; `  v7 ^0 l; [3 z
        }5 }6 _1 T- t- g% j  n, f( N
                                if(count>USB_BLOCK_SIZE)
$ a5 W. S6 ]9 L: N1 }& `% V  ]                                        count=USB_BLOCK_SIZE;4 P" T+ [: Z8 {
        if (flags != osFlagsErrorTimeout) {0 {  }0 @+ |5 l# P8 T! J) l
          i = index & (USB_BLOCK_SIZE - 1U);. v# w0 H& s- a1 d
          if (i == 0U) {) V: j3 I! J8 s1 F# Y) U9 S
            count &= ~(USB_BLOCK_SIZE - 1U);
  p, B! Z+ z2 j% s; c          } else {$ ?; O! Y: k0 E/ ^( B- B& @
            n = USB_BLOCK_SIZE - i;8 `* ]+ c6 f0 J* M# A
            if (count >= n) {
0 f* f! u# V  L( \% f0 z5 p& x1 n3 {* O              count = n;
: w# `. }9 j# W7 P            } else {3 a# k" R0 C9 w7 R# ^
              count = 0U;
2 f5 k( W8 V0 P; r! j3 e6 x            }
  B: |3 \' u% L" z" c9 E6 ^  L          }7 |! z+ g! U: b+ T* u
        }
8 M& s1 J/ Q) ^8 |# W        if (count != 0U) {$ Z& ~  n& G! W* `- b
          TransferSize = count;' P/ u/ ]: C* R) M; ~( [; n+ M$ ^
          TransferBusy = 1U;: l8 G$ H/ z2 g# M( ~( V
          SWO_QueueTransfer(&TraceBuf[index], count);3 h8 E2 v8 m) N6 F5 A- e& p3 y
        }
* }1 _" S$ R: g8 T/ P; s      }: k! M- E, ~  H0 q$ }* P4 t, T
    }3 T* H+ q5 E7 x$ R# g
  //}
9 ]: @7 `: M. B7 l. T                return 0;
" M& u7 N) s6 [% f}
; [7 D9 s- y! h  N- O利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
& j& p$ M! p: z1 c4 n, s0 r#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).$ B( n/ y. b7 V! t4 z
static volatile uint32_t SWO_EventFlags=0;
5 h: X. }6 o6 r' W2 B  l% _static volatile uint32_t timeout=osWaitForever;6 {/ r! \- H# P' e  W
static volatile uint32_t timeWait;
5 y$ x- e% c' J- A, i/ h函数改为这样
2 ?7 R3 d3 r4 Y, ~0 c/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
" r6 I/ H1 h6 L9 g4 I5 H* T  //uint32_t timeout;; R, }% J0 r" C3 d* C$ |
  uint32_t flags;
5 \2 w7 B' T; Z  uint32_t count;
9 i0 y$ ^; C- I8 n2 d  uint32_t index;
4 O6 P" R" ]( I5 p( A; m  uint32_t i, n;
' v5 b, S8 O6 g1 |& ^7 _" v  //(void)   argument;* ~8 G7 a) C; n8 x
% K: F% P  T  B+ V4 t: a
  //timeout = osWaitForever;
* h. ?, b2 z7 F: p3 e4 |0 Q! _* F4 P  M0 U1 X+ X
  //for (;;) {: Q- O0 A4 b9 e; R" E9 ^
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
, J" t6 ?" E. O- k) x% Y8 l                if((SWO_EventFlags & 0x01)==0)
3 s2 K+ c+ R0 p+ [                {
7 A+ s" c6 U7 n  I0 s, Z+ m                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了  x$ ^9 k9 o% M
                        return 0;
. z+ L; g0 b1 D                          B) U! H# K  J  y8 a
                }/ V6 d& t7 ^8 K9 n7 ]& s8 c
         
% {* v0 ?& l/ ^7 [  h! r0 Z                flags = SWO_EventFlags;& q" ^/ l" B. C7 X) ]
                SWO_EventFlags = 0U;
; u" k( _$ z4 B6 x% m8 O    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {' Q. a3 p7 G4 c- B8 ]
      timeout = SWO_STREAM_TIMEOUT;
; E, L* y. G, c" J( f& m      timeWait=DWT->CYCCNT;
9 o4 Q% {8 |0 q/ H2 ^    } else {
) n* W+ u2 L5 ?4 t      timeout = osWaitForever;* Y- A2 B" n  _- }
      flags   = osFlagsErrorTimeout;5 t& A% n! m+ m
    }. E' q1 j( }4 Z4 ]: s$ C4 k
    if (TransferBusy == 0U) {
4 \; M  x+ _& o" Z+ M      count = GetTraceCount();
3 j8 D7 z* `! T, G0 Q' y      if (count != 0U) {
& E$ L. }' Z, N  y# z( _        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);! p$ t( w7 s6 z" c  ?
        n = SWO_BUFFER_SIZE - index;
& p: g0 s$ I( B. `        if (count > n) {$ w& Z9 ^5 D! c) \
          count = n;  u  v1 L$ c4 A1 v6 W4 f9 t
                                       
/ H% |/ x9 ]! J& s/ v/ E        }
0 l5 V* ^8 y# |% U) ^2 |                                if(count>USB_BLOCK_SIZE)* U  \2 i; c. q( H" e; `4 |
                                        count=USB_BLOCK_SIZE;
& w- r3 T9 E6 a5 O! o+ V        if (flags != osFlagsErrorTimeout) {$ Z* r* w: R2 Q
          i = index & (USB_BLOCK_SIZE - 1U);
8 y8 z: b0 v2 D- D( M5 Y, m9 s          if (i == 0U) {) z9 D8 y) F# D
            count &= ~(USB_BLOCK_SIZE - 1U);
+ h7 m3 q6 j2 `) B) [  ?          } else {
* i7 P! e: R, [            n = USB_BLOCK_SIZE - i;+ j7 N/ O; A, j1 l+ t+ M* }
            if (count >= n) {
" L6 Y! L7 a' R: |2 q  ]- S8 a: b              count = n;: B9 r/ z; w' m& L4 _1 A
            } else {( J" q& o; k  ^+ s# m, O
              count = 0U;- K. i& e. B& b. |! j) V
            }
& }8 }0 d& L( V- B* v" A0 t          }
& [/ X9 d* ?8 g& v, d        }: ]0 z, i7 t. Y+ y5 c" Q) k4 @, K
        if (count != 0U) {( a* w" t% @% x, H* u
          TransferSize = count;2 K8 ]" n) L. K. R. q* o
          TransferBusy = 1U;
( Z) Z) m; a% ~& f! ?' N) K          SWO_QueueTransfer(&TraceBuf[index], count);" Z9 u/ K3 ~. R+ S/ f' p, D! B; M1 I
        }6 x1 |5 s6 c- C) x# l. t7 w8 |, C
      }3 D6 Q$ I8 r; K; O2 g% X
    }
" b( G  c, S5 A6 `% L0 B) L( e. Z* y  //}
# x4 @+ J9 j& F! O                return 0;
0 y; M2 ]! \- Q5 k}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了
! z8 o- y* U5 k# j
7 y6 A% t) C8 aCDC部分暂时还没加入,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,少了这个等待时间,能增加端点的传输速率1 R8 i' \( q3 k/ O8 V

: M; r: y: ]8 T
$ I% I9 g3 |* e3 Z- {( iint main(void): x6 ^" X% u9 ^
{2 Z% I% D  }; D$ T( y( r3 L, Y
  DWT_Init();
. `3 H  Y& B7 ~" t        DAP_Setup();
3 x" M8 _+ K5 X! u2 F  USB_Interrupts_Config();
. [6 ~, C# N, S9 |9 C8 g3 @# |+ B4 t6 W  Set_USBClock();4 {1 _! [6 ^- }/ h! U3 F& [3 l4 {& o
  USB_Init();
0 S% s! [$ g% Y9 J* G2 W7 z& G        //TIM3_Init(35999,0);
' b$ a3 G- `2 e& Y, S7 ~+ g        //TIM_Cmd(TIM3,ENABLE);, }& b( H3 j" e; E: [9 g+ a8 v
        - k& C* o3 s  l9 ]8 I" a
        $ [8 h2 E( v. q, U6 l; S7 W
  while (1)
* R$ V5 P( ?" ^/ w  {
7 K, M; Z. V9 c  U1 u                DAP_Thread();# q! w, a/ D( T1 R/ @5 z  C
                #if (SWO_STREAM != 0)8 b- Z/ u7 P( l0 u
                SWO_Thread();$ C# `- n5 I8 p/ \1 H5 T) x9 e
                #endif
. s1 n! {  ~( L  }
% y: {2 |/ s7 J& s: v}
& c. V8 L- r+ F& L% ]; a
/ \1 S, m: V9 @7 D( k" ]对于DAP_config.h的IO配置我是这样弄的
. S  D1 z' o" e8 S8 f///@}- i6 b3 {% O  f4 p
// Debug Port I/O Pins
% \1 @2 K) f. I/ @+ h/ _
9 {) t) Z; y$ q; L// SWCLK/TCK Pin                GPIOA[6]# B6 X* ]7 n2 f
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198" t& D. q$ Y% `3 B+ Q
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
- y8 ^3 m3 y/ o  u% j# [
, K9 c& I8 @, p" h6 k7 V, A6 c// SWDIO/TMS Pin                GPIOA[7]
; T4 L4 `$ V5 |#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
- a& p5 f/ f+ I: U' ?#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C
& Q( J+ l& Z+ p. W4 e& _* u8 U3 D9 _0 F3 Z: b; g6 a7 w
// SWDIO Output Enable Pin      GPIOA[7]
* a7 z, h$ D/ x8 {4 z" v#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
6 X* Z$ L- o* |( }: N                                                                                                                                *(uint32_t*)0x42210070 = 1; \
' e$ o: \$ D# `4 V; V3 V- ]) p                                                                                                                                *(uint32_t*)0x42210074 = 1; \) A0 y; J7 p) F" n; o) P5 N
                                                                                                                                *(uint32_t*)0x42210078 = 0; \; D# x, u9 b/ d& m
                                                                                                                                *(uint32_t*)0x4221007C = 0;}5 H! q9 Q$ a  D/ s' O1 ]4 [
7 V  J! M$ O2 g$ [/ j
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
6 @/ h/ a6 a$ h$ S- Q# e5 w! t                                                                                                                                *(uint32_t*)0x42210070 = 0; \
2 R( D8 R: O: S$ b" w7 B/ G' A                                                                                                                                *(uint32_t*)0x42210074 = 0; \
4 S8 P/ z  n' o; a& j+ a# b4 U                                                                                                                                *(uint32_t*)0x42210078 = 0; \1 H& U' d& ~- k0 P( i/ N1 ^
                                                                                                                                *(uint32_t*)0x4221007C = 1; }8 ?2 l; W( m- g4 b/ s

2 b) g  d" M7 k8 S8 }/ R; v+ r// TDI Pin                      GPIOA[8]
) O  {+ n% t* c, q: S' U#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0  e1 f/ l  B, D4 Y0 [
#define TDI_IN                                     *(volatile uint32_t*)0x42210120
  }2 @) v' w) x" T9 X! Y0 s  j
. V. S2 @9 B! z2 X3 W& W; y! d0 F( @3 K// TDO Pin                      GPIOA[10]' v% J4 |4 u- ^0 d
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
8 i( u# [9 z5 ]  G1 F#define TDO_IN                                     *(volatile uint32_t*)0x42210128
; q9 z* q! i& d, z+ }. u, U
8 f6 J$ q1 C8 |+ ^8 r; F// nTRST Pin                    GPIOB[3]
1 ]) B% n3 C$ v% w: `( `7 X# c#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
! x, Z7 Y6 S: G8 d4 f#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C' @6 `( M  t0 Z7 K
+ Z% d8 A3 N" ]) [. L' T* C5 b" X
// nRESET Pin                   GPIOB[4]8 H0 t+ k9 K; D, ^
#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190& [7 R7 ?/ w% T6 v" E6 L
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
1 M/ \( E7 g  c2 Y) H0 Q2 y, m
  i. Z( A7 ]! p// nRESET Output Enable Pin     GPIOB[4]+ p8 s$ Y9 v4 a  f8 }. i+ g. `/ V
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
, M) C3 J. E% n, x                                                                                                                                *(uint32_t*)0x42218040 = 1; \
: O' k1 h. J3 s: [! Z" r                                                                                                                                *(uint32_t*)0x42218044 = 1; \. d$ n0 E. p7 P0 ~
                                                                                                                                *(uint32_t*)0x42218048 = 0; \  |$ o7 s0 ^) b3 t
                                                                                                                                *(uint32_t*)0x4221804C = 0; } ; i6 K! j! I/ @  P8 {6 t# t$ a  Q
7 e% Z$ G2 E$ R8 L/ i
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
2 w/ T7 @& ^- i' e9 u                                                                                                                                *(uint32_t*)0x42218040 = 0; \% D7 b, ^& k. K0 w1 _: a
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
  Y: A, l! m% j+ b$ l! v9 e4 c                                                                                                                                *(uint32_t*)0x42218048 = 0;\
8 W) E6 u% Q8 N) @! v+ H" ^                                                                                                                                *(uint32_t*)0x4221804C = 1; }
; I" a; J6 O5 c( C- f7 v8 Y8 d4 z3 p4 t/ r( ]  U" a- t
$ T0 @( t+ u  W
// Debug Unit LEDs* @0 z& \+ T- T: ~% q- h

- U% K/ I, q& }8 R! S0 t( w// Connected LED                GPIOC[13]3 ?) x7 e) U5 T; s" p! G
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
; K$ X1 a" E  \4 d' F5 v#define LED_IN                                                       *(volatile uint32_t*)0x42220134
4 b! G- C6 B3 P
) f: Z1 e+ G9 z$ t* K#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \! G; v8 b( L0 A
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
7 g% V* ]% Y; |3 I0 ^+ J                                                                                                                                *(uint32_t*)0x422200D4 = 0; \
" O& d/ Z2 {, s: X+ v9 N; X                                                                                                                                *(uint32_t*)0x422200D8 = 0; \% v( l/ c4 ^! B
                                                                                                                                *(uint32_t*)0x422200DC = 1; }3 T1 U8 {9 p5 v: O& P. _7 A
// Target Running LED           Not available  c" v1 e3 z1 d
) K& T( N5 ~4 o+ R  ~- N
// SWCLK/TCK I/O pin -------------------------------------) _, m( N  F8 Q3 x+ w

4 K- e5 A4 K. y" l: I4 ~& k: Y& t$ F/** SWCLK/TCK I/O pin: Get Input.
0 x, \5 v5 b4 P4 v# x\return Current status of the SWCLK/TCK DAP hardware I/O pin.
$ P' C. c' X6 _! r& |  L*/" u) I' n/ G6 \9 ^1 G' A/ i* ~2 h5 w6 }
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {0 Y; ]4 k3 x  R4 x' d
  return (SWCLK_TCK_IN);4 v$ a8 h7 l8 y
}
5 n2 O6 S+ k( H8 k$ j& v" `2 ~! Z/ v4 F
/** SWCLK/TCK I/O pin: Set Output to High.
# x1 s5 ^  C' t* y* DSet the SWCLK/TCK DAP hardware I/O pin to high level.
6 Q* D3 y4 Q' z*/
) v' I! ^! L+ y4 d+ W0 |' y__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {; Q1 r, T: [# Q! a& ^4 Z5 P
  SWCLK_TCK_OUT = 1;
8 ^7 a1 c) q( p5 |}
& X8 n* B9 [* C3 Y: ?+ H" A7 k9 u: L0 h1 j; n( W" x$ `
/** SWCLK/TCK I/O pin: Set Output to Low.
6 N& r" `6 q9 i- ?2 q$ N, ZSet the SWCLK/TCK DAP hardware I/O pin to low level.
/ X* Z& w$ g9 z/ y*// e: |; O3 p! K# }" s+ p: H
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {  j: v& d$ t) z
  SWCLK_TCK_OUT = 0;
& B4 H& X+ {% l}
3 y  l7 |1 N/ i# S9 _; w! @7 \9 j5 \5 _7 Y

8 Q' G# ?6 a! m5 |8 x( g// SWDIO/TMS Pin I/O --------------------------------------
: g3 D2 e* z! W2 Y* w7 h4 l3 D; N- D3 ~9 b$ [
/** SWDIO/TMS I/O pin: Get Input.
* U1 R+ l7 h3 t4 b( D  w) @; o3 T\return Current status of the SWDIO/TMS DAP hardware I/O pin.
2 h) m" [4 x/ C: g% V& ~*/
0 O" m. a. ]; n- P1 e9 O__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
6 i& e" l( g1 T3 H  return (SWDIO_TMS_IN);
& C) O' i0 C" l7 ~% V0 R' i}$ G; `, p9 E. Y6 a

4 n+ _3 w4 z) _  u6 H7 U/** SWDIO/TMS I/O pin: Set Output to High.' ?7 H- f1 R  e" f: {% q
Set the SWDIO/TMS DAP hardware I/O pin to high level.+ h! `2 _2 N& T# O4 N. f
*/
- }4 \6 e; ]: B# ^( Y) m__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {
: M1 l! _! G7 r- O' o6 V7 X  SWDIO_TMS_OUT = 1;7 I, k  s- U1 f: h' g
}$ Z- c3 b7 P! V% R2 k
9 w  B2 I- Y% m4 q2 h. m) [
/** SWDIO/TMS I/O pin: Set Output to Low.) R% m' L, Z7 B! O
Set the SWDIO/TMS DAP hardware I/O pin to low level.
3 O) a. k+ x, f  M$ g: W$ ]+ [/ c*/  y; p! \- ^& Y, E# ^1 B. t( G
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {. d2 t5 J) D4 l0 ]
  SWDIO_TMS_OUT = 0;
, X! [4 Y: ]6 T$ h, B" r}. f  N1 w6 ]& G3 n: Z6 C

' F/ T- z/ L2 \' W" n# X% w/ S$ V6 Y. X/** SWDIO I/O pin: Get Input (used in SWD mode only).
+ O' `6 K7 ~% W\return Current status of the SWDIO DAP hardware I/O pin.6 b/ O6 a7 Y$ A! a  t; L
*/
& z6 k5 f) a0 i__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
, q* w" j" F! ~0 A; ?$ V3 E3 I  return (SWDIO_TMS_IN);% I# P5 t5 z( c( W/ ?( K* t
}# N4 {& ?2 b8 Q- r+ v) W9 K
$ g6 H; r3 f3 S2 l7 c1 S7 \
/** SWDIO I/O pin: Set Output (used in SWD mode only).
+ b3 ]( ~8 l8 _, I, L: Y" m- }3 p; L: S\param bit Output value for the SWDIO DAP hardware I/O pin.. K: ^$ \$ U! M& P
*/
! j/ I1 X, |9 x__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
( ^4 _0 d% D9 k  SWDIO_TMS_OUT = bit;
6 v4 u+ u' D- N! a, d}/ _4 W5 D' Z; A4 v
; Q. l; F# [. W$ M, P4 x3 ]
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
5 C. ?1 u& L2 i& w8 I5 M# mConfigure the SWDIO DAP hardware I/O pin to output mode. This function is
, x; A; _) d5 [# l. A  H6 [% zcalled prior \ref PIN_SWDIO_OUT function calls.
, j5 W- U8 T+ t5 }  _*/
2 @5 Z3 e, c" i) z0 ?  A__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
, ?3 ]' i- Z* g9 L5 ]  SWDIO_Output();9 {2 p1 h9 e) G; d, s
}
! U5 Y, z  @" @
3 T( }5 h* ^, H/ x6 W& h/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
# }- s0 ]0 Q' g2 C' d- u( rConfigure the SWDIO DAP hardware I/O pin to input mode. This function is- w; m! r7 m6 O$ E
called prior \ref PIN_SWDIO_IN function calls.
9 T6 @! e3 b* h' F$ W: t) `*/
6 b2 K# y$ F1 H' N__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
" c; }% k  o! b0 v' P, E# j  SWDIO_Input();% U1 f: e) b: W) _# t0 d; Z
}
( ~! O0 Z0 g$ `& k. U3 b2 p/ @( z. f! ]/ l$ z7 ]/ C
楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
' Z, U$ U( v. ~8 v* H即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
7 E, c7 b3 Y3 P
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版