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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。. u) ]& x- M* {- c& G
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
( [, W7 Q) b9 _8 e) k除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
* a1 ^' a; `0 v( Z& K
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
; ]; _7 V6 g5 |& \% B7 P
( x8 z: a5 ?+ z0 |软件复位是另外一种情况,需要向目标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  V+ w0 |/ l2 x5 V
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
; C1 T/ x$ Q8 t$ z5 h6 F
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
8 Q% T4 G$ x$ G' V4 `你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。
- {1 l+ S: W/ W& h2 {! W9 V# i6 f9 a. _% X
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 # D7 M8 x- d  Z7 S- G5 H$ a2 S% m
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。8 a9 h7 g! `. U8 U

0 v2 h0 d/ R: F/ c: p
( Q3 n# R! f% S/ K) `4 y& w
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
" n( T) I; M, l3 |3 G- |
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
0 \3 J1 P9 o2 h! I$ f
起点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系统,轮询执行
. ^9 j: m5 ^3 K* r/**/ U: I$ X2 r3 h( U! Y+ Z
  ******************************************************************************
+ D* `+ P6 u3 u! B& w! |0 b  * @file    usb_endp.c
9 u5 Z' }' e) Y2 d4 F  * @author  MCD Application Team0 {# {4 X5 H. \3 k& v; S3 X
  * @version V4.1.05 W/ r& Q! y  }, A8 Z0 y* z
  * @date    26-May-20179 {9 \5 }* k& W
  * @brief   Endpoint routines
: d  E- n: A& ~9 q3 f4 c& F5 G' z- i  ******************************************************************************
7 B# |* X4 l9 t( S, Q. E  * @attention+ L- c6 p7 p( s0 f: h, P
  *
5 f, ?# D' |; {4 `$ ^( ^6 v  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>9 ~7 `* K& {* \6 z
  *
, M' ], `  I/ Z2 f  * Redistribution and use in source and binary forms, with or without modification,
- o* T) E: Q6 r  U* b4 G  * are permitted provided that the following conditions are met:
: r8 D$ }! Z1 `5 Y  *   1. Redistributions of source code must retain the above copyright notice,
- C/ J- m- j- a$ G7 C( G* |  *      this list of conditions and the following disclaimer.
7 V: ~/ N1 z$ v2 I7 [# X  *   2. Redistributions in binary form must reproduce the above copyright notice,* a6 V3 G3 m- q
  *      this list of conditions and the following disclaimer in the documentation
  B3 E; s2 s8 [& C* O  *      and/or other materials provided with the distribution.
: {4 V4 E1 Z) n; X5 a  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ Q/ s7 a+ q+ N4 J9 T6 u  *      may be used to endorse or promote products derived from this software* o$ ]( _$ R% o5 N% Q8 T% o/ {
  *      without specific prior written permission.8 }9 ]1 ]! K, c9 m
  *1 G' N- Y8 t' y$ N: f8 }4 I
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS") V' }# y; b( i7 H' j
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; m) Q  h. ~; `/ [. ?, k  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
$ |9 l3 ?; R  A, C. l% @  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE. D1 C2 C: B/ E& k5 E2 c+ P
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ S. B, j- J0 D! Z( A/ b  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8 G$ p4 X) h; j% S: y" I4 e+ D  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
& ~* U: O! F4 e0 J- j; u  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,3 ^3 o& h' ^5 a  O9 s$ g5 l
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
& K: Q2 k1 X9 p' T5 l  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# d! X6 r6 Y+ C+ `. y
  *
& Y( P) Y4 |8 w: B; ~0 ?) F9 E- T1 g  ******************************************************************************& C  `! _7 n8 V4 q$ D7 d
  */3 b% J1 y" f3 e

* B: G- D, y' c
; ]1 `% H, T: n9 B3 J( Z- D6 p- c/* Includes ------------------------------------------------------------------*/9 B% A% \5 z) Z
#include "hw_config.h"& \8 C& x0 C) e8 l9 k
#include "usb_lib.h"
1 g! u6 [3 X3 c; B/ @, J0 X$ J; j#include "usb_istr.h"
4 D# U( H4 ?/ a6 c  r#include "stepper.h"1 D" D$ x0 C( o1 k4 N
#include "string.h"; `# r# ]( P9 T; G& S

  s' ?, y- o0 s& ?3 A3 x9 t#include "DAP_config.h"
9 p- l7 u* t* }0 b, L6 G* p3 U#include "DAP.h"
' o" O( g& h% ]/ o
' e2 V0 H5 F2 T' l
' [  u- R3 S# |+ i, Y. r/* Private typedef -----------------------------------------------------------*/
! A, W! E; |: o& z/* Private define ------------------------------------------------------------*/
# x. |* Q/ M: U( f/* Private macro -------------------------------------------------------------*/) T( F# x$ n) c
/* Private variables ---------------------------------------------------------*/
" U+ Q0 E" t0 n2 {static volatile uint16_t USB_RequestIndexI;     // Request  Index In! F! j5 P6 ?* Z* u; X* X
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out6 k, N$ K) t' Z2 P* k5 P* W# C
static volatile uint16_t USB_RequestCountI;     // Request  Count In
! S: ?; p, U) }- G" k$ [static volatile uint16_t USB_RequestCountO;     // Request  Count Out
  C7 _2 W% @" @static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag
4 V+ H( h8 l, v$ R, f* Y
2 A! x8 Q  w" n; ?static volatile uint16_t USB_ResponseIndexI;    // Response Index In( ]/ B+ e* H2 f, V( q& @
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out  g' `* [* M/ L7 s
static volatile uint16_t USB_ResponseCountI;    // Response Count In
5 i$ x1 {: u- U  |0 `; \static volatile uint16_t USB_ResponseCountO;    // Response Count Out
# Q& q$ e, n7 q6 N( Nstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag4 E* `1 ]4 Y! c; [2 @; I
static volatile uint32_t USB_EventFlags;
$ Y0 z' J' W: [9 z. h  r
$ Y/ D1 m2 e6 _; tstatic uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer! m; W! y5 \0 P
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer9 O$ C8 e+ w( v- p2 w; ?
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
, `  }9 Y$ G$ o! U7 K& [
/ a, s" i6 l9 J7 k' h, K/* Private function prototypes -----------------------------------------------*/! S# ^; h# \# R3 T# t
/* Private functions ---------------------------------------------------------*/
3 J! V# R0 U9 i/ w% m4 q# t1 D. r/*******************************************************************************
- G% D5 `; l2 A+ z* Function Name  : EP1_OUT_Callback.& T/ F+ X) A5 W2 c. w2 P
* Description    : EP1 OUT Callback Routine.' n% r/ ~0 O2 E6 w' H+ C  N
* Input          : None.0 A" L/ L% v: M
* Output         : None.) X# }0 t% {8 F( v  x$ v5 }
* Return         : None." x! E/ m; \2 `/ P; z
*******************************************************************************/
# O1 E; ?) a4 n6 {9 o+ qvoid EP1_OUT_Callback(void). @6 _$ k+ k  L6 ~! ~
{
4 O' I+ F/ ]- O9 @# h        uint16_t n;
' i( F8 g* u3 \! h& `* g2 I* B9 j! E
        n = GetEPRxCount(ENDP1);
/ t) y# c, b4 j& y4 [        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
$ ^' w; t  G  F! n        if(n !=0){
8 t) G: Y2 C, _! w3 C+ B  Q. b# Z                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {: F, H5 G/ B! {
                        DAP_TransferAbort = 1U;* ^9 ?' x( z/ l9 J# e0 N+ e
                } else {: k: s8 a8 D; p& l/ ~' s
                        USB_RequestIndexI++;0 |& H0 `" j, k$ X7 \' U% E
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
( p* b9 i# N: x- {% D2 Y, k                                USB_RequestIndexI = 0U;& j5 O$ d& X( l+ g8 @! c  u
      }2 Z% [! z' I. X* ~
      USB_RequestCountI++;
& Z5 B1 L  i7 P& p0 `* ]& p5 N0 ^+ v* s6 D        USB_EventFlags = 0x01;
. r/ ~3 I8 _2 r6 ]  H    }2 U. `2 z, x. X2 w! y9 n! P, c0 r
        }        7 y: i! ~9 A  K# D7 Q: m+ f
        // Start reception of next request packet
8 p4 V! n4 n% |+ ~1 Y        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {) a. n  j# v; `! X8 G! D
                SetEPRxStatus(ENDP1, EP_RX_VALID);  W7 F8 ?4 s8 _: f3 @" a6 W0 O$ v
        } else {" d. B# K# K" T; z
                USB_RequestIdle = 1U;7 R- b+ p: a+ F. L% g* w# L6 t+ ~/ g
        }                        
9 U7 |5 l5 q5 v5 B. r7 t* r; z}
6 T  S1 ?1 l7 w2 q4 h0 j8 _/ \, n9 ~9 j
/*******************************************************************************
0 n* j2 M6 s. X$ B5 q. T* u* Function Name  : EP2_OUT_Callback.) X" a. P# ^: @. ^# T
* Description    : EP2 OUT Callback Routine.- I2 R5 D+ M3 E% X5 o
* Input          : None.( S6 ^) V6 M2 K
* Output         : None.( R- y* f) p- q" X; _- o
* Return         : None.& H  Z7 K) Y% }( P
*******************************************************************************/' E! V5 S8 G5 P) q. A5 X
static volatile uint32_t TX_n;
5 `2 j! r, Q) i; {$ Ostatic uint8_t *pbuf;5 k& ?7 ~. l" f* w$ s/ W
void EP2_IN_Callback(void)* f3 [/ P& j, L0 D9 \# H
{0 q; Q( c7 s& J, s  [6 h/ P3 l, X
        uint32_t a;8 u6 S% ]5 [2 R; X
        if(TX_n>0){
7 q" Y2 Y- M) D& X( c' J, M) P6 l                pbuf+=64;4 M# k" o9 Y4 }$ Q
                if(TX_n>64){( w+ @  i# I0 q" a. p- y# U
                        a=64;
+ g$ i. |  D9 e8 h, V! |                        TX_n-=64;; ~. {, [' b9 i
                        , b& k* N. u4 y5 I- W* _
                }else{1 p2 x" h1 T. g
                        a=TX_n;! w- V" h# R. Y% Y- t; J7 g8 X
                        TX_n=0;+ a& _3 i) H! {
                }+ H- Y/ o0 V% F5 Z! j
               
" P" x6 `3 x& _! f7 h        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
7 Q& `- t' l8 @* Y# B$ U        SetEPTxCount(ENDP2,a);- M4 C! p8 H9 I7 z
                7 O1 ^  s3 X$ R$ o
        SetEPTxValid(ENDP2);
% C! E% @9 y& g& g2 a* d5 _, q        }else{% F( W- r) L3 e2 G  d# {/ Q
                #if (SWO_STREAM != 0)# c' G% M+ w$ ^
                SWO_TransferComplete();- ~9 L! d) x% H6 T
                #endif
  G: \0 j/ s' J% @9 _; s        }( A2 h5 k5 h* h  w" D, v
}, n: I8 @: T$ W0 ~
$ E/ n& i% ^% m* m4 h8 S
/*******************************************************************************7 R# g  z9 j) M& a# a
* Function Name  : EP1_IN_Callback.
) C+ {) r" ~. {/ P$ E8 l. d1 P( I* Description    : EP1 IN Callback Routine.
/ Z8 v* L) `, L" M. M) ~, q* Input          : None.
9 x' Q' R3 T( z* Output         : None.9 ~0 P% P& C; x! S1 z
* Return         : None.( G* |5 Q& g) K, m9 h, W6 c/ |
*******************************************************************************/$ i+ u0 Z  v9 g8 Z: [
void EP1_IN_Callback(void)
2 L0 Q  ?' Y. K3 N! }{1 ~+ j, u9 ?' i8 o7 x" P+ W3 h
    if (USB_ResponseCountI != USB_ResponseCountO) {
+ I/ j0 j( i% X0 D( s4 j      // Load data from response buffer to be sent back
- B; c# i4 F- F- T                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
$ N& c2 i1 d" v% n2 a2 i) t1 y& }                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);' C+ ]% V6 K% K- }& }
                        SetEPTxValid(ENDP1);                        $ R' B- ?/ p' a; V; o) P1 x
      USB_ResponseIndexO++;; o/ m% l: g  P  @& W7 ]
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {1 B& e) m4 {1 F" g3 Z
        USB_ResponseIndexO = 0U;
/ O: B5 ~: o9 S! a      }+ f' }& |4 p' `9 W& M! O
      USB_ResponseCountO++;
% n& e1 w8 l  H; w! f6 f    } else {
, d/ D' T! }) T: F) \      USB_ResponseIdle = 1U;5 v5 V5 C  w1 T
    }  ! C+ ?* p0 [, F& W. E2 F! }
}
0 \% l/ Q% h& N# D' |+ I; ^3 X) A4 X/ b$ j9 L& i6 p/ G
// Called during USBD_Initialize to initialize the USB HID class instance.( w. C& [- ]! I, J  o1 W  L
void DAP_FIFO_Init(void)
" r' a! j  a- i* M{7 y. f& Y2 o1 C
    // Initialize variables7 ?0 c9 z- ^) c
    USB_RequestIndexI  = 0U;1 j! M4 m5 i4 [& D2 f
    USB_RequestIndexO  = 0U;; G* h$ f+ R# H" M3 a
    USB_RequestCountI  = 0U;1 x! L$ [( d2 c% W7 x
    USB_RequestCountO  = 0U;
* T4 G" ^0 F) D' _    USB_ResponseIndexI = 0U;8 K4 V8 i: {8 S: b0 X( {
    USB_ResponseIndexO = 0U;
* L8 M8 s% v. L% d    USB_ResponseCountI = 0U;) I0 a9 b9 Q2 \4 ^' h, a
    USB_ResponseCountO = 0U;
7 C9 F6 c$ n5 `4 x* F, p    USB_ResponseIdle   = 1U;% V* i9 ?. m. o" v) C+ O/ h
    USB_EventFlags     = 0U;
) U' F: z+ a* s( o5 Q5 F" ~. G% u& M}- i6 G) v' T: x: c  N+ g
  l2 B, @+ |) P$ Q
uint8_t DAP_Thread (void) {- g3 K6 W% O9 u8 F2 p0 f! j. f
  uint32_t flags;
% {, k, P, e" J- K  uint32_t n;
8 j$ I7 p6 F) x# j- Q9 Y6 I( V2 v. C$ ]
  //for (;;) {
2 k* a7 c) K0 h& a' X6 D1 D  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
5 O! v4 y6 Q& u/ h# v  b; I; \/ O                if((USB_EventFlags & 0x81) == 0)
0 i. ~3 J6 l8 d- n                {
4 a. a3 B7 R4 y                        return 0;$ V% Q* g7 E3 |* x
                }
3 g' T" D2 n! \4 R& ~# H1 q/ ]* v, S                USB_EventFlags &= (~0X81);
4 b5 W: x4 L+ G- F, Q" u               
) i) K- h. J2 A! i                                       
- g3 J: _! }8 G( G& m    // Process pending requests" T/ B& s  n! v& r
    while (USB_RequestCountI != USB_RequestCountO) {
2 Q, I4 X7 r- O- S' ^                //if (USB_RequestCountI != USB_RequestCountO) {$ b7 `# X# U6 v! h9 q; }; o
      // Handle Queue Commands3 {( n9 b' a; \  H3 ]
      n = USB_RequestIndexO;
1 V+ |$ e/ f. L: f/ L      while (USB_Request[n][0] == ID_DAP_QueueCommands) {; j2 d! h$ s6 j( e  M! o
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {7 M# N% x% D6 n8 E4 c
        USB_Request[n][0] = ID_DAP_ExecuteCommands;
" }  r0 g) o/ S* p( h        n++;
$ b/ ~" d, ^6 Q# r& ?7 g4 c5 Z        if (n == DAP_PACKET_COUNT) {
6 i! t) I: x7 G4 Q! H, W0 n          n = 0U;
0 N  q" x- V/ [4 I2 a! ^5 ?        }# }! r/ T# C1 Q6 |
        if (n == USB_RequestIndexI) {
* N0 j7 n5 _6 O  k          flags = USB_EventFlags;
7 t' i% _2 H) A2 u+ t          if (flags & 0x80U) {
- i  U, h# @$ |- T' b+ @            break;
! C0 }" u6 [  x. r6 _  i3 d          }
' Q2 l. w2 V9 w$ t7 M' K' V: ^        }
7 I% ~/ h. J3 j# p! k      }
& x/ l' Q' C* B9 ]( R
4 M1 d4 p% Z  j& Q3 o9 _. G8 n      // Execute DAP Command (process request and prepare response)6 T9 f6 _( P  |8 w4 w; U, i
      USB_RespSize[USB_ResponseIndexI] =3 R9 W$ y1 D0 P9 b- y# q: ^0 P8 K1 M
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
8 v- g. o  L% L' x: C& a$ C; N0 b" P, b3 A
      // Update Request Index and Count' H. W9 V+ E8 F% q& k
      USB_RequestIndexO++;
9 `5 F8 g+ u  r0 M, D  s6 ]1 j      if (USB_RequestIndexO == DAP_PACKET_COUNT) {
9 C3 b0 \; O% ^4 r# U        USB_RequestIndexO = 0U;+ {& _& n; Y( G; p; }$ {
      }
2 d! b) u" |4 |+ r      USB_RequestCountO++;( H$ i8 {- X/ R
5 Q' G- h- e: O$ J! N
      if (USB_RequestIdle) {- b5 A9 I# t% [# t
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
2 y5 `  {, X3 _4 m  w          USB_RequestIdle = 0U;# ~7 B- ]! h, j" o5 h# G2 M
          SetEPRxStatus(ENDP1, EP_RX_VALID);9 M' _" E  G/ c0 F* C9 a7 I5 L& Q
        }
1 x- t. T' E$ i3 \, A3 m      }
, }( p7 j( [1 t, s# e# e! s) Y! L8 U; p: ^) _# ]
      // Update Response Index and Count
  u4 h& @  l- m7 d! d      USB_ResponseIndexI++;
8 m. L2 b, W0 t( h2 ?( k* D7 o      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
; P0 F, \1 ~/ ~: |# P1 j        USB_ResponseIndexI = 0U;" Q9 }- |. d% L, i. R" E. L
      }" P, K& U8 @3 u/ r, w6 B, ^6 D% x
      USB_ResponseCountI++;1 u7 |" Q6 ~* w9 Q' |+ T7 w/ l
" K/ K3 P6 |9 P: ?/ S: v
      if (USB_ResponseIdle) {
) F7 `* g1 j, g7 x1 C/ I1 g8 `        if (USB_ResponseCountI != USB_ResponseCountO) {+ ]4 y; T" s' c$ a
          // Load data from response buffer to be sent back- C* Y7 N, E9 Y/ y- l% c, p5 |
          n = USB_ResponseIndexO++;
% w8 X/ D" C0 w, L* p. x2 r8 |          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
5 b, L1 y" T4 C: u, |6 `2 Q            USB_ResponseIndexO = 0U;+ w, z' k! Z" {  c1 i% _+ W0 W
          }" P4 L+ F" i/ [/ [) y: D5 R
          USB_ResponseCountO++;1 ?1 M, j. X; a$ O
          USB_ResponseIdle = 0U;
  m. s8 b8 z2 s  j7 Q/ Y3 [          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);' h2 ^, V- m$ K2 l/ W
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
% M9 x$ u) D: ?! V0 g                                        SetEPTxCount(ENDP1,USB_RespSize[n]);* m8 a' v4 G2 a) w
                                        SetEPTxValid(ENDP1);7 n! J  w5 a* B. Q" o
        }- Z7 P) k9 n6 q0 g: v6 c
      }
* U( D: U# ?. X# a% f    }+ O, J' H; n% W! z. O' N
        return 0;
5 t# j; M+ U- b2 Q! w}
+ p1 r, m% G) T+ d+ d
( Q1 R7 T5 l, w+ i. ?8 t& l8 i! W// SWO Data Queue Transfer
5 X$ w& t/ W  a  t//   buf:    pointer to buffer with data+ e' k9 W# q4 E4 l/ ^; c! z* M
//   num:    number of bytes to transfer
; F! }. D1 n) W2 G/ v: V! p( y  Gvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {0 U1 q, f: I5 ~' p9 r7 ?3 c
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);/ z0 _3 J$ ?) C$ m) Q1 _% s( J
        uint32_t a;
6 o' k* U# N+ P        
9 `" m6 j/ }; J5 j        if(num>64)4 x, i: A( f) g+ h
        {
  W; {. P4 w3 M" l1 Q3 s- u7 j5 O* f                a=64;' C7 q" G. j" X# P  m" [- J& ~
                TX_n=num-64;! P* l; x; o3 w6 A5 e8 }; H
                pbuf=buf;
/ K. S/ ]% d& U8 w0 E; I
& t" X7 F- n! U- X6 `; l        }else {
1 c8 j/ S; M9 a6 z                a=num;2 M& L7 L. S9 X
                TX_n=0;: U9 k+ C! ]1 H/ H( K
        }5 E# C+ `- o3 b! Z; M( f0 z. g
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
0 ~6 `5 ^* t/ N: r0 p* ~        SetEPTxCount(ENDP2,a);
5 g2 y3 S/ A( p0 P        SetEPTxValid(ENDP2);
9 k9 m0 k5 z; d  W+ t}7 r2 N3 l* ^2 W

7 D  q- D6 N0 H, ~( o// SWO Data Abort Transfer) O4 h1 `4 Z. u2 j) }& M; d
void SWO_AbortTransfer (void) {$ \- A1 T+ R# i# F
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
* B9 _& o% O3 a" W        //SetEPTxStatus(ENDP2, EP_TX_NAK);
9 J; o+ U0 A; x3 X9 t% m        SetEPTxStatus(ENDP2, EP_TX_DIS);
+ h: J  N& W8 b4 G6 T. \/ b        SetEPTxCount(ENDP2,0);
2 r, h# j5 X0 f: r6 b        //TX_n=0;2 {+ q3 H" `7 |( s
}1 ?- N7 ]6 a; _9 }5 a/ k/ F' U, G
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
% j0 s& ?# ~( h0 j" E" A+ G3 ^' P( b' z* y& z2 S
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
6 |9 d- `. p) }  U% r# H- l; ?& fDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了
4 b9 K( n. A1 a( F6 H* A__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {) C4 W; t1 \$ J. R: k& S+ O  d$ Q
  return (DWT->CYCCNT);' ^/ L" n: g; p. U
}
, ]" R0 z: g4 g$ ~2 ?4 U( [0 i: w* n
% ]0 F( m3 U$ i3 a! |5 fvoid DWT_Init(void)
7 K. y7 o1 ^4 a) ^. P! E{( K; m- v# }$ |
    /* 使能DWT外设 */
7 |0 q# M+ d6 B    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                : r, g' @1 ]4 t! O  ^+ }+ A
- h$ l; O2 ^' w2 R2 e: n0 k
    /* DWT CYCCNT寄存器计数清0 *// C$ x# Y9 W% b" J6 I  {6 b' e4 B
    DWT->CYCCNT = (uint32_t)0u;
/ B' h9 f% t6 F% L( n8 ?' q5 H3 C
' c$ B% _5 M4 _    /* 使能Cortex-M DWT CYCCNT寄存器 */
. t( h+ n& F5 S( M( x" G    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- c+ N8 a  v; Y  w  j. H}! j: s/ R) U( L8 F$ w! Q; {
        
- F6 F8 Q  ?! I& h! S  U
4 a0 Y% }9 [& k$ d然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
; m! Z4 F- `/ Z& u9 Y  K5 U0 [9 ^8 U7 F0 g
然后改为使用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不香么?
- Y( Q# x4 a9 B' T声明这个变量static volatile uint32_t SWO_EventFlags=0;
5 @* c  j8 P1 x; |3 l在SWO里每一处调用osThreadFlagsSet的地方都改为如:* Z( T3 ]" V' s/ c: |
//osThreadFlagsSet(SWO_ThreadId, 1U);
2 u' l4 o1 P, ~# h- |SWO_EventFlags = 1U;; p+ P- X- l/ \/ y: J
7 Z1 `8 C# ?5 Q8 H. J
4 U+ H' E: j7 A1 o7 z, g
// SWO Thread
9 L% a% h% t  P/ @9 z  j! ?/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
4 u4 W& s6 w/ m9 M  //uint32_t timeout;6 ^4 Q$ j9 E4 `
  uint32_t flags;
9 H" O' \+ a) s3 S3 d4 Y5 W$ ?9 Z  uint32_t count;$ O; P! V( N7 G7 C$ J3 q
  uint32_t index;" C' X7 [7 n2 `% @( B) H
  uint32_t i, n;
& `& \4 |1 Z$ e- ^+ X( ^/ P# I  //(void)   argument;
; K4 V1 S2 m2 R7 @% y- V' v9 H/ R5 @: e% M) h% p6 J3 \; ?6 N# ^+ M
  //timeout = osWaitForever;
' i3 j, ~  F* ~) @- x+ _1 a$ U) u  W$ v) M
  //for (;;) {* ~) e7 W( M9 ?  [
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
' W( T( X) |  R0 q! I; d                if((SWO_EventFlags & 0x01)==0)return 0;
/ W/ e( K! M' K; k5 m         $ s% Q3 a# w; q
                flags = SWO_EventFlags;# k, H" g& _1 A' ]0 O" ^  [
                SWO_EventFlags = 0U;
3 l. x& f7 X" M# y. Q    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
8 L. u5 `* A& O! b0 _9 S      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子& T5 E7 ^0 a+ h/ i, m+ [
                        ;
1 p7 c/ i7 [* t' Y4 g    } else {
" [) q1 ?7 G: q4 T      //timeout = osWaitForever;
# o, P* P+ {' N- S% G& I      flags   = osFlagsErrorTimeout;
# j" A  ]* u3 [. s+ G/ D    }
8 _. S; H  k  m/ q( |    if (TransferBusy == 0U) {
( h/ `2 [( c/ F& k1 u" K9 i* X      count = GetTraceCount();
( c" Y/ Z" ~5 w2 w2 O8 V/ c  V      if (count != 0U) {
7 r& Q7 X1 p9 r( s        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
: g0 K; O- j! f2 r: Q- l' A. z, ^# _1 m2 M        n = SWO_BUFFER_SIZE - index;
: W! z4 C( a0 m. E9 P8 c        if (count > n) {3 `4 @) f$ B- A+ `6 c5 _" d  c) G
          count = n;: T5 v' ]  m3 |/ w9 v
                                        0 b; S: x8 ]' T! a( f# n
        }
$ D. z( E( q5 v) V3 [3 B                                if(count>USB_BLOCK_SIZE): S* g8 }7 E) g- D7 y! j% B  }( \
                                        count=USB_BLOCK_SIZE;
- X- \3 t) K( ]- @6 ~        if (flags != osFlagsErrorTimeout) {
6 w* V6 a" E" ?8 t5 d          i = index & (USB_BLOCK_SIZE - 1U);8 u' r  t, }1 f! c
          if (i == 0U) {' s9 S- U% G+ U. a( u
            count &= ~(USB_BLOCK_SIZE - 1U);
3 C1 i0 F; e  _  o1 ]9 f4 w; ?          } else {
) P, e2 F( d- b# P& d            n = USB_BLOCK_SIZE - i;2 n7 [1 `2 j4 l' i( C
            if (count >= n) {
) L( N' x/ u& L* v# a5 w7 F              count = n;
* A7 [' [7 i( }0 ^+ y& L/ f% C/ L  J            } else {; u+ @# Y8 O  \
              count = 0U;& Y, U  o1 S0 O3 L2 Y1 m3 g+ v
            }
: v9 E4 ^$ k( J. J  B: Z; I: \          }
" `9 W: i# F" q0 k3 L/ |        }
: q1 P' r$ D- M( U0 Y        if (count != 0U) {! F" x; e, l! ?% v2 T
          TransferSize = count;  F4 K+ {. w* V9 F+ h0 T
          TransferBusy = 1U;
1 H3 N  D, ~8 m          SWO_QueueTransfer(&TraceBuf[index], count);
$ Q  ^/ `1 Q: c        }
5 a& N* o" c+ [1 S1 S- q- T      }
+ I" S! J. r2 C# x1 y$ a    }
& P9 F- O7 e* m6 H" u& p) I7 `) K  //}
  F7 \3 g( R4 u. a9 C$ g                return 0;" M9 Z4 W9 g0 I  V, c5 X
}
, @' K$ ]' W% B; X9 D利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.# F/ e9 H7 p8 t. Q0 F9 L6 P$ l' H
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).- o1 n* w5 i( a
static volatile uint32_t SWO_EventFlags=0;
3 A- C0 x6 r' v2 `static volatile uint32_t timeout=osWaitForever;1 {# z9 @7 m7 Y# o
static volatile uint32_t timeWait;
/ U5 ?. n! x! I; Z# D函数改为这样
  h  H0 z+ n# Q2 ~: O! m; n/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
+ \3 R7 @, @8 ]3 G& l6 p5 O5 d& [  //uint32_t timeout;
5 X3 B( d9 f% C) @4 M8 l9 X  uint32_t flags;
7 m- r( S7 d1 O3 j  uint32_t count;
2 C9 ^. h3 z) J. _, U2 o3 T3 W4 O  uint32_t index;( ]) D$ w5 C$ Y8 s
  uint32_t i, n;) _, p3 q9 s7 x1 o) Z# V5 D' k
  //(void)   argument;
$ i  O: `0 U6 B& B0 Z7 v
& o9 g# k  Y. Y4 R' z  o  ?: W+ a  //timeout = osWaitForever;
2 J: r. H' J1 N! k3 t+ d& j! _% j- `% d3 e% ]! M1 S
  //for (;;) {
& w: c8 s. Z& z( t9 @! M    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);; i* Y+ N2 p' D
                if((SWO_EventFlags & 0x01)==0)
8 l8 Q- l* C8 q* h2 x/ P% Q                {
# ~0 f' x6 l5 a3 C/ p6 S                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了- [: b' R9 R  `8 f
                        return 0;4 `. S: _7 I* U
                        
* E5 u! e. H7 o4 V' l                }
0 K: o9 o  Z0 _% ]         0 V3 Y' ?" D, I5 l+ V
                flags = SWO_EventFlags;% Y# a" O3 W& o" }- L7 J
                SWO_EventFlags = 0U;
) S4 @& k1 k4 b- c    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {$ G% k# j" ^# s
      timeout = SWO_STREAM_TIMEOUT;7 ^" X* h5 i# f2 Z  E
      timeWait=DWT->CYCCNT;+ s- C. f# h6 |6 x/ b! ~
    } else {
. \, X) M: {9 N9 k      timeout = osWaitForever;
( a7 J. f, A$ J; y% h6 g6 p4 L      flags   = osFlagsErrorTimeout;
3 i; m+ M9 s4 k; A" Y    }
! h9 E5 X" \) \) [    if (TransferBusy == 0U) {
' b" z, O( }, }, h( J& @- _2 C      count = GetTraceCount();4 G; h6 l; y: M1 }0 b
      if (count != 0U) {
. s/ o) R5 T, Z) X        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);+ h* u/ p; D5 I
        n = SWO_BUFFER_SIZE - index;3 q/ f# A) v3 A/ Y8 B
        if (count > n) {
3 }# K# A/ N) H/ H. [8 ?* u9 ~) K1 E          count = n;7 g& z' r6 W/ O8 m  ^, \8 I
                                       
5 b0 h8 {5 T3 T4 F) l. x( l# [; I        }
( Q6 M# J, i: B" O                                if(count>USB_BLOCK_SIZE)
, @- ]# Z9 V' `; X- ]                                        count=USB_BLOCK_SIZE;6 d2 H- _8 P2 {* ?7 t
        if (flags != osFlagsErrorTimeout) {
2 ^) a" ]& m8 [: Y% ~5 w" k          i = index & (USB_BLOCK_SIZE - 1U);
. i& w8 Z$ C9 k' p% K: L4 s) B          if (i == 0U) {4 }7 b/ b2 r( G- H& ]' D0 K
            count &= ~(USB_BLOCK_SIZE - 1U);
  e; }9 d! v/ R          } else {( B" a; y& a6 D( K) f
            n = USB_BLOCK_SIZE - i;" `" l4 n6 e5 a4 C
            if (count >= n) {- v- i5 M8 `! D% I& p% A. A- g
              count = n;
, I3 S4 s* I  v4 h7 {3 i% u            } else {
  R9 U+ D' |6 i3 f6 d6 b              count = 0U;0 c" ]* W# _' H) }8 e2 F
            }
& }7 \' s" E  V, }0 O$ N: f          }
# y0 k4 {: g3 X0 X- y1 f) H        }
7 p  s/ v8 r3 ]7 \        if (count != 0U) {
1 Y) B# D7 e/ M( b          TransferSize = count;
. s/ |  q* k( X; L          TransferBusy = 1U;/ X  \0 }! T2 B9 \
          SWO_QueueTransfer(&TraceBuf[index], count);8 Q+ ?5 W4 l! ^
        }" ]; S4 n8 U8 h  e$ e
      }
: b; d3 |" d+ o1 X# b/ b    }* R4 W% J9 ?( r: w5 X, O6 W
  //}6 P& f! z4 D0 X5 C! w- n
                return 0;' }! j# |8 y8 X9 d* O( z1 ~
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了
: n9 K5 u- @7 P: z& n6 \1 _& s- K" q3 e: 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,少了这个等待时间,能增加端点的传输速率$ U, R7 R- F) B

* N0 I# X1 ]0 f* R- p
* J0 ~! i5 B1 l2 Zint main(void)
" t( J0 p: V0 w9 S6 c) |1 h/ j{% m7 O  Y  }( [( e) B5 E! Z9 i
  DWT_Init();
7 v8 R. j. k: x& T3 `! ]2 K9 D        DAP_Setup();6 L2 t8 j$ ]  ^5 I
  USB_Interrupts_Config();
5 `5 p; x, D. g! p( o  Set_USBClock();3 E9 p, `% B$ ~3 {
  USB_Init();
6 D* v) H$ @8 ?0 u3 f        //TIM3_Init(35999,0);# e+ ~2 B: T+ n6 }5 x6 `
        //TIM_Cmd(TIM3,ENABLE);3 o) Q' |% l$ `" j; R9 ?
        
: C+ A& Z  }1 d6 T! s+ w2 X. T        + z5 i! D9 [9 w+ `7 @" T
  while (1)
* A0 [# k+ T' L* f1 |  {
1 }. A1 R- z% m" Z9 d+ V6 W) `                DAP_Thread();4 y9 R& T8 A. Y0 R0 P; i8 ?
                #if (SWO_STREAM != 0)( S% L: j2 b+ t$ c. V) U
                SWO_Thread();: g0 `$ h( t% P, [  d3 ^3 T( l
                #endif
* ~5 ^3 w% |1 \% N( T' O  }
; I' D$ s: m  c}
: E' c6 ~# m/ y9 v, \6 w5 m% R. f8 t6 u0 X1 O8 j) o
对于DAP_config.h的IO配置我是这样弄的1 l3 f/ Q* p  E( I( Z
///@}
7 u0 ?( S, p8 F, O// Debug Port I/O Pins- H! H( I& L# C1 b) X8 J

9 `  J3 H9 M9 F  b3 O// SWCLK/TCK Pin                GPIOA[6]
* @* j* M. z2 v  T8 u" v. t7 h#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198* _! N8 k9 _) ?
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118! g( R  f. K$ V6 _. L

% u$ n4 I' u3 G7 H) U// SWDIO/TMS Pin                GPIOA[7]2 T0 {* T6 F; J# w8 p
#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
* [0 ~, [# P1 N8 d+ i. T#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C
# x" c5 N' Q# @  S6 j  p6 [: w
9 b4 ~- X! d* `+ t. s- S& f. ?( ^// SWDIO Output Enable Pin      GPIOA[7]
" ?/ ~" C* u* t& ~9 |' ?2 I' @& i#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
. ?; a1 ~6 A" t- ^                                                                                                                                *(uint32_t*)0x42210070 = 1; \
$ b4 d( m9 K3 l. X; |* ?( a                                                                                                                                *(uint32_t*)0x42210074 = 1; \  w9 F9 q3 F4 h0 |
                                                                                                                                *(uint32_t*)0x42210078 = 0; \
5 k- q' o& |. H' K4 e3 o                                                                                                                                *(uint32_t*)0x4221007C = 0;}
& d- F: u# A0 Y+ |! ], f3 y# E8 z( f8 I! i/ {" J+ Y2 {
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
) o% n6 q" w! g% g                                                                                                                                *(uint32_t*)0x42210070 = 0; \
+ t6 j8 i- y. V0 Q8 t  U                                                                                                                                *(uint32_t*)0x42210074 = 0; \& a* ^" G( v! q9 ]3 F
                                                                                                                                *(uint32_t*)0x42210078 = 0; \4 Y6 C6 o8 V9 O
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
6 V+ Q& {; \8 k7 o2 O/ N
* A# k, m3 U7 G  u& y// TDI Pin                      GPIOA[8]
  ]. W1 b9 F# v#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0  b. z! r" ?1 k
#define TDI_IN                                     *(volatile uint32_t*)0x422101203 U! w, U2 J; v, z8 A5 a% j( k' I  C

2 i8 O  k, y0 o, E( d; P// TDO Pin                      GPIOA[10]$ E/ n. `' L. Y$ F' [
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
, x6 Z5 h4 d8 m5 b#define TDO_IN                                     *(volatile uint32_t*)0x42210128
7 n7 d' @, [5 R0 ^% g5 g: l
; T4 ^# n) A- r% V/ @% c0 @3 t// nTRST Pin                    GPIOB[3]! X, M! p6 m2 X1 G( G- a
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C1 z$ [6 ]' K8 o3 r+ U3 v( u
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C8 a% \8 X4 s2 _3 o6 ^% n

2 u# ]9 l' F" n& I% ]6 x& E// nRESET Pin                   GPIOB[4]
7 e' G& B- z& A#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
3 p9 A1 ^# M( H' L2 K: l#define nRESET_IN                                  *(volatile uint32_t*)0x42218110. S6 e; h5 E% V: p, i
4 [& \, C2 n$ C
// nRESET Output Enable Pin     GPIOB[4]# v+ U; \; u; m+ i' u) O# H5 [8 b
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \, B' p; s1 m' B" A! G
                                                                                                                                *(uint32_t*)0x42218040 = 1; \
' Y7 h! H) z+ b; k* _                                                                                                                                *(uint32_t*)0x42218044 = 1; \+ i" Q1 F. z  c  V0 f9 d' b" X
                                                                                                                                *(uint32_t*)0x42218048 = 0; \
3 m! D& l" {6 }  L                                                                                                                                *(uint32_t*)0x4221804C = 0; }
6 o) X* G- W6 D: M1 B( F) y2 y6 N2 {3 P: N( q3 {  m/ u1 V+ d  A' O
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \. M8 e0 n/ W" i
                                                                                                                                *(uint32_t*)0x42218040 = 0; \
8 ]8 ]- p; e/ I% G, E                                                                                                                                *(uint32_t*)0x42218044 = 0; \8 I2 T5 |0 z% h5 j0 ~" U1 e
                                                                                                                                *(uint32_t*)0x42218048 = 0;\. p# I5 N# a# v; Q
                                                                                                                                *(uint32_t*)0x4221804C = 1; }
6 R1 Y; ~1 C* Q2 L% Q( U1 x% ]* e8 B

3 j* J: u- U$ O: I// Debug Unit LEDs0 d8 G3 L* O0 i. L

4 ^' b6 X) v2 O8 s' i( U// Connected LED                GPIOC[13]
* v% O! d/ J0 m6 P3 a, @#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4) H- Q! I0 }! L4 z" d5 j1 `
#define LED_IN                                                       *(volatile uint32_t*)0x42220134/ Z% f" E9 l( }8 B

7 X6 {% j3 D, V! H) n#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \* @2 k; U( k9 h: Z) Z+ @$ @
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \7 i( r6 {' h- r9 x) _1 f  q, L
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \8 V- O$ v0 ?/ a% k* @# }  T! J/ A/ r7 O
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \" ~) g- _% y5 L0 s9 T( O% g) }
                                                                                                                                *(uint32_t*)0x422200DC = 1; }+ ~$ D5 E& ?# O# u
// Target Running LED           Not available. a- h, b; F! o' `: `4 e1 e
( b; R' C. ^) S) i, n9 R, ~( `% h
// SWCLK/TCK I/O pin -------------------------------------
7 G+ u" I! b3 k$ ~
# V# z9 M- l* T8 X/** SWCLK/TCK I/O pin: Get Input.
# U  n+ n4 \# Q4 \. t* R7 K6 p' o3 f\return Current status of the SWCLK/TCK DAP hardware I/O pin.* m1 \; B* E# ~5 P
*/) |7 Z& g$ _1 d
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
0 H) a0 [. D3 C2 O& [, ?3 `  return (SWCLK_TCK_IN);
; \$ g- c5 v1 }$ F8 `3 ~1 N5 r}
, ?+ L! W" D/ }+ j' ~6 s+ z
. V# I: B1 X0 ?: Z2 z* u/** SWCLK/TCK I/O pin: Set Output to High.
1 X* \5 o( `" {( F, u" \Set the SWCLK/TCK DAP hardware I/O pin to high level.: n) c3 e. M. r" c+ f9 P7 l
*/
6 V: K" u" v7 t$ ~& `__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {
6 A) L& L& J0 ^! Y0 j  SWCLK_TCK_OUT = 1;  Q( r4 P  ~# Z& L
}
, ?% G9 |: A; S" ?! D- |% |8 N3 ~1 f) U0 L3 m
/** SWCLK/TCK I/O pin: Set Output to Low.% L) h9 m3 h8 K8 M: H! |* t
Set the SWCLK/TCK DAP hardware I/O pin to low level.0 j0 X3 M: w. O
*/! H, p% H; a3 @* D0 f
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
# a. q3 S$ ~* |7 n9 P/ p  SWCLK_TCK_OUT = 0;' a' e/ Q3 _& b/ A  `" C# M
}& u1 f8 ~- C, S7 F5 r( o( w0 c

  e! G( d( w1 S( s6 I9 @# p4 h/ Q
& s5 K1 x0 Y( g// SWDIO/TMS Pin I/O --------------------------------------
) o" ^/ H3 [  G# h. e4 k5 M9 }
# j1 V2 W: \5 q/** SWDIO/TMS I/O pin: Get Input.+ R* r; c6 ~7 _4 d
\return Current status of the SWDIO/TMS DAP hardware I/O pin./ u! A4 \  |# c, h8 P; t
*/
3 W1 e$ }  }1 |8 w__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
2 j3 u: e! f& K& B/ d  return (SWDIO_TMS_IN);
5 f. ?* B1 ^* L6 C}
. _2 e: @6 Y7 E6 {8 K5 G- Y- o6 r. J8 D0 Z8 E4 f
/** SWDIO/TMS I/O pin: Set Output to High.
9 I, |$ p& B; a/ H3 P, O; FSet the SWDIO/TMS DAP hardware I/O pin to high level.
. v1 `* D. |0 Y2 k6 Y! O*/
" D/ C- F1 z2 B9 Y1 N, q+ w__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {  r3 p! ]! ^. x8 h
  SWDIO_TMS_OUT = 1;
& Z; U4 r; U5 y" ^% h}; A4 V# n% q& O: d# n& e- w
' Z  ]7 I; n5 U/ F2 y9 [
/** SWDIO/TMS I/O pin: Set Output to Low.6 m0 x( g: v' E/ h. H
Set the SWDIO/TMS DAP hardware I/O pin to low level.
3 U& E: g" i" X( o$ @*/
0 A7 x) ], Y: b( O) s5 k__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {% m: W2 |& Z/ _% ^/ c+ `, Q
  SWDIO_TMS_OUT = 0;% z; c" L& U5 \6 |% ]
}
  v7 z, c. b6 o  F, i1 B* Q: @/ n9 ]1 X& A- }
/** SWDIO I/O pin: Get Input (used in SWD mode only).8 J+ f0 L# T7 t# P( e( X5 ?& |1 |
\return Current status of the SWDIO DAP hardware I/O pin.
, r/ ], p9 t4 {2 ]% t: k5 u. [*/
7 A  u- _) }% f$ Z# S0 x__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
  J1 @( y( Q; I0 c: w9 \  return (SWDIO_TMS_IN);. G6 D* k5 X+ h* t! P& ?6 j2 @( C
}
  Y5 }4 c; n3 Y# I/ P# e9 G. ]! a1 y
3 J5 u( T# p: o8 c: R9 z/ I# x; j/** SWDIO I/O pin: Set Output (used in SWD mode only).+ `) w% b- ^3 o3 W
\param bit Output value for the SWDIO DAP hardware I/O pin.% s8 N; D0 w. y! w
*/
# t2 L2 A7 t! G7 p3 x1 i__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
, f0 h. a6 g0 x8 M  SWDIO_TMS_OUT = bit;
1 a1 Q4 s8 o- P1 S6 d}3 l. Z: F- C% O. ~

( l9 R4 F* c+ Z% B; U/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
9 j7 h4 h& ~/ A1 y4 s+ q( Z: W* mConfigure the SWDIO DAP hardware I/O pin to output mode. This function is& Z8 m* G, L2 ?% _" s2 f" V1 r
called prior \ref PIN_SWDIO_OUT function calls.
. i# q# ]5 J6 F/ [! S*/
/ L8 v5 _+ |& D1 l  W' e__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
! z# M, F* J% t) X8 v% w2 s  SWDIO_Output();; s/ @" C% S5 _# x$ b
}+ ^( Z' E& V8 \; a9 v
  w, A/ w& t7 j" V% x
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
  O, m/ J6 r8 m( JConfigure the SWDIO DAP hardware I/O pin to input mode. This function is! v1 z3 y: l3 k% V& g( p
called prior \ref PIN_SWDIO_IN function calls.7 o" g7 U* l: v9 h6 J6 l
*/' L6 R) f( h7 w: B! |9 v9 i
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
" s5 U2 ^# G3 m8 P  SWDIO_Input();
6 V, A5 k; }0 t}
/ \. k3 _( X& j5 {# ~
: o. _" Q' @# H9 D$ x楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
. V, D  q+ {; c. C2 m; z即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下& d0 ^2 i; n' ?8 p) ?) U
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

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