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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。5 ]  D% K3 Z$ b7 H
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
/ n8 M5 S+ U% x5 U除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...

. s% J8 ?, _  @# C2 S! R我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
% y. H6 w! n; Q: t: |( Y" z- ^# s2 n9 i1 r
; {9 i* |0 k8 h) u' y软件复位是另外一种情况,需要向目标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
$ Y* A0 H: `0 A5 Y5 f! Z可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
& R# s2 `. t; _5 j/ q& ~* B+ N+ Q
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
" X& G; o8 n. J1 R* e" w( V1 w你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。
8 n3 N" ^9 f" t1 I5 E+ s% S/ l; s, ^9 Q# L  m6 H. Y
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
+ l# M9 O  B$ j, l或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。% U) O) Y2 Q( ?1 h' N* l
0 o/ i  U% P1 j5 P( K) Z* V8 e8 N

% e! A7 L$ [2 P0 S& |; F
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?- J9 t$ O' w/ \& I) l, [" ^( h
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap
! a% @6 n3 t& z  J
起点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系统,轮询执行
( n. h8 Q- d, `2 t( F/**. A3 ~+ E% h- E3 k. ^2 a
  ******************************************************************************
# x3 ?* ^) X; ^  * @file    usb_endp.c7 F* {+ `1 T  s# U& K5 U3 n
  * @author  MCD Application Team3 a5 O- o5 G/ |
  * @version V4.1.09 P# C; J* F! |$ L
  * @date    26-May-2017# i+ r- p- e  e9 ^
  * @brief   Endpoint routines
$ {* M! B- M% V8 u( _  ******************************************************************************
0 G4 z; G5 X3 W- B& [! R( q  * @attention5 Y6 k; C5 T# A3 y6 ~& i  c% ], g
  *
5 M8 E9 A" a6 H+ ?" \: h4 c/ Q  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2># R( q; p* v* A- A
  *
  C* x! E8 c6 ?8 x. ?  * Redistribution and use in source and binary forms, with or without modification,
2 {" }4 m7 u. Y& b4 `9 Y. }  * are permitted provided that the following conditions are met:* j7 e  T% a, s" Y2 f) O
  *   1. Redistributions of source code must retain the above copyright notice,
4 U* ~/ m# r1 X) `( p7 P  *      this list of conditions and the following disclaimer.& J+ y# T. L8 d9 C
  *   2. Redistributions in binary form must reproduce the above copyright notice,7 `7 m* i2 e# Z
  *      this list of conditions and the following disclaimer in the documentation
/ }7 {0 h1 I0 s$ O5 i  *      and/or other materials provided with the distribution.
+ _% d: w2 S8 R% W) k% T  *   3. Neither the name of STMicroelectronics nor the names of its contributors( ~( i1 k. y1 o. {" f
  *      may be used to endorse or promote products derived from this software" k6 I# V" X7 f/ n  O  I
  *      without specific prior written permission.5 ^9 A5 P7 C! V3 ~' _* [
  *) W/ @# l7 r! G- c
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"/ g7 D* c, W- Z
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% k* t( j/ G( f3 W  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  o) T7 ?, G1 g5 M0 f; a  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE' F4 w; h8 X+ R# x  q. ?# }" q* y  }
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6 [, f0 j1 n3 h" q4 G+ `) v7 e  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR, P- h9 C  S: P3 Y5 J2 O
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ [6 F; ]( A9 d- [+ N4 N/ J  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  @/ R4 C/ T1 |( T" o
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE/ c2 B- S; v. E5 ]8 [' f3 I
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
) X! ~3 {# n0 _# P( R$ O* R  *0 b8 f5 p6 ~+ T0 u
  ******************************************************************************$ E; s4 P4 ]; d  g, E; [. p
  */0 A7 ]: `# x/ K! e

- B' e% a, p* f) c$ a7 J
" P# m$ f, G5 D+ G/* Includes ------------------------------------------------------------------*/  E% M6 w* u8 G8 e, L. W: T  r
#include "hw_config.h"
( [/ x5 F& Z2 h: ~* F; W#include "usb_lib.h"0 @% K* e) d/ Y& W
#include "usb_istr.h"
2 c+ ~' v: |+ M! f, A#include "stepper.h"
$ `; f' v0 z; Q#include "string.h"
0 a( {. Y4 {, j
' F/ n+ e: H5 w" v3 P5 K#include "DAP_config.h"
; G: T$ B) L* [4 \' R3 f#include "DAP.h") d$ A( {9 d& g; @, {
2 p2 O6 M: A* A; D

9 h2 ]/ b- ]+ p- H: U+ ~- J9 d/* Private typedef -----------------------------------------------------------*/  E$ }/ t, x& I! l
/* Private define ------------------------------------------------------------*/
% l2 b6 E6 t1 u/* Private macro -------------------------------------------------------------*/5 V6 c# r: U. ^9 `' i* R
/* Private variables ---------------------------------------------------------*/" a5 g- {. O" E( z( H. |
static volatile uint16_t USB_RequestIndexI;     // Request  Index In
! e8 o$ x8 n3 V/ Y/ k1 Jstatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out) p5 ?% a8 j$ F6 C- U- {
static volatile uint16_t USB_RequestCountI;     // Request  Count In- H' W! C. _' x& w) Z& H; q
static volatile uint16_t USB_RequestCountO;     // Request  Count Out
: i: V% G0 ], H% r( h- D3 {' Y* A( [2 Jstatic volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag1 K$ W) [  \, S' }  t
+ u, F3 M! {1 {
static volatile uint16_t USB_ResponseIndexI;    // Response Index In2 N$ C) X2 p' `' b8 D) @
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out  e. V6 g) H6 V1 u% R9 v8 }
static volatile uint16_t USB_ResponseCountI;    // Response Count In& ?, r' l% a5 S
static volatile uint16_t USB_ResponseCountO;    // Response Count Out
5 u8 p7 L' v: h- Q6 mstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag. n3 W- k9 D2 C2 A
static volatile uint32_t USB_EventFlags;
. E  f* X4 e* W# m- Y9 j; k7 ~) v' h- [" @
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer2 g) F9 L$ [$ K8 F2 O/ n/ }
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer* f" ]: n5 Z) g
static uint16_t USB_RespSize[DAP_PACKET_COUNT];4 \7 M6 Q, }! I  D
1 @8 X# i/ i8 N0 Y! I8 H, U
/* Private function prototypes -----------------------------------------------*/9 F, w- u8 r4 {1 V9 t
/* Private functions ---------------------------------------------------------*/1 o; I' ~$ W/ x9 ]  y$ @9 {" m( N
/*******************************************************************************/ a( p  X' [6 a
* Function Name  : EP1_OUT_Callback.
/ O0 K  M$ z* E, Q, v* Description    : EP1 OUT Callback Routine.
( L/ B( j9 T- N  D. k* Input          : None.
9 G$ \5 O! y# @3 i. G8 r! P* Output         : None.& G+ o" Y& l$ T9 [  e
* Return         : None.
) w# N" |- l8 H/ J* w*******************************************************************************/
1 O- T. e7 _4 evoid EP1_OUT_Callback(void)" Q" H" B, B# t4 E7 K5 {7 e( c
{
5 g# C1 ]' Q9 G7 ^* K, M        uint16_t n;; G' T, X6 \+ U8 I4 r
7 }, U3 D- V5 l
        n = GetEPRxCount(ENDP1);
' G) ?# W7 W" g1 o6 [9 d# @        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
& s+ c# n' ?! p( A# ^. D        if(n !=0){; y2 T3 ]" r# j
                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
  t8 j7 k- u5 S0 ~: u) V                        DAP_TransferAbort = 1U;
# Q, }* g' X7 m' t; N4 E                } else {: n. t7 X! p7 t4 Z; z: m; M9 G, l1 _
                        USB_RequestIndexI++;
$ D$ e' ?) Q5 J4 U      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
" b; Y* t) [3 [; `7 A/ i                                USB_RequestIndexI = 0U;7 _6 G5 u- t" u/ s! M* G9 N
      }
( |# K) i" x; k) U& L      USB_RequestCountI++;
) q; n: g6 t0 ?/ e7 S        USB_EventFlags = 0x01;
# y6 A; Q% l" H4 r% o; `% i! o& a& U4 P    }$ g5 M' A8 C, T# [, w5 J$ m9 ]
        }        
0 ~8 |" {7 M7 W0 G: L        // Start reception of next request packet' u/ K" e+ x, I1 H# m# {  _" G  R
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
% n4 e# ~# a4 p5 l' J                SetEPRxStatus(ENDP1, EP_RX_VALID);
% h1 S- o" P. e4 F" J$ j( h9 M        } else {
  I- G- s; s/ m                USB_RequestIdle = 1U;" A9 n! U+ r" z$ \9 _* l  A
        }                        " J. a! X2 |. F7 U
}: d5 ~' z+ s  @
1 w6 W& @: U0 Y! ^8 O
/*******************************************************************************
: }4 n. H+ ]$ V8 R* Function Name  : EP2_OUT_Callback.( ]6 m6 A9 t1 F2 x! A; g) b
* Description    : EP2 OUT Callback Routine.: |8 `2 G! B5 f
* Input          : None.9 h; O' O; }# N. d# F  s# Y; h
* Output         : None.
6 I* X4 r$ f2 _- q# S* Return         : None.; O8 X% L8 p& y% d& c2 g
*******************************************************************************/( ~: T. _/ Z' g! e4 g. Y; Z
static volatile uint32_t TX_n;
  i; _) D! t( W( Lstatic uint8_t *pbuf;. J6 _; h! I( u& \' p2 T
void EP2_IN_Callback(void)
" F5 t& o( E  v! g{
2 u7 _9 j) f' h( a5 y8 C0 o        uint32_t a;; h# Q. o+ u( D. n- Q* w
        if(TX_n>0){
6 Y0 j# L2 `) h! k" j8 ^# Q7 @                pbuf+=64;
' l" q! d. A* Y# h! ^3 U* g" _% O                if(TX_n>64){! e) N2 F8 o! z' d. _' T7 W
                        a=64;
, O$ ~4 F1 w- @, H. L/ D                        TX_n-=64;- T" i3 B; \6 |4 _1 u6 {) q6 ~: A0 O  n
                        
" u* p, ~, E. d5 _* z& ?; U                }else{
! T' N$ |0 Q! t& @9 D' r                        a=TX_n;
# C) @4 M1 V, [$ G3 L6 l# s                        TX_n=0;* e2 k' w* [5 `" r& }6 L
                }
; o) q+ D1 N7 @" p                : ?$ u, S& G! [3 u1 u$ y2 K
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);2 @2 ^3 u% N% E1 D* s7 \! W
        SetEPTxCount(ENDP2,a);) ?+ ]5 T; P% n$ `! y
               
$ h: j, m6 |  O+ E; i  p, A        SetEPTxValid(ENDP2);0 O9 C" v% R9 E0 I8 J& F
        }else{# H& y0 g/ A/ }1 J
                #if (SWO_STREAM != 0)% K9 L2 \& b4 D2 r- ~
                SWO_TransferComplete();
8 j7 K' p2 |$ i- s1 I9 q                #endif
( V6 t: H- r$ _4 r. i& f        }; Q: q4 ]% t0 P5 k
}
+ U( U4 [* N$ j" G7 X8 Z+ l1 b$ S+ d0 J. A' |7 x4 ^
/*******************************************************************************
! m- _; f7 u; Y# T7 Q" l* Function Name  : EP1_IN_Callback.
5 s6 X- L, s5 G- y* q* Description    : EP1 IN Callback Routine.6 J9 }! T2 [2 \5 a% Q2 B2 h
* Input          : None.6 |4 D  L. S  z9 f2 O1 Z) @, r
* Output         : None.+ U3 @2 Q1 q  u7 l3 W! ~
* Return         : None.
0 C$ ^2 d" v# t/ _$ d1 M5 x*******************************************************************************/
( D* i% z2 M" b6 z* gvoid EP1_IN_Callback(void)
% z! W- K0 m# B6 X' E1 v, S7 [{$ X6 h" Q7 h' R
    if (USB_ResponseCountI != USB_ResponseCountO) {
3 ~: i+ B) K3 q) u* m$ p1 a. O      // Load data from response buffer to be sent back
% A2 q' o$ A; z1 J0 W8 ?4 U                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
+ ?- e) Z; w9 X* p8 ]+ Z                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);# I! }, @5 [, }! a' k3 K- U- H
                        SetEPTxValid(ENDP1);                        8 E' h0 i: |; ]  Z9 u2 A
      USB_ResponseIndexO++;
6 n# r% Z5 U" [$ ]: U0 z4 F) b0 o* }      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {2 ?% W" ^0 L4 [) _
        USB_ResponseIndexO = 0U;. D% V; X% \9 T& Z& i- {3 ^
      }! I) B+ a/ _' x- E. ?
      USB_ResponseCountO++;
% Y& F$ |1 @# V9 `7 j    } else {
! A; B. c3 k" R8 ]! t7 c7 k' y      USB_ResponseIdle = 1U;
* k; P' `2 r1 u0 c* C& {* G1 w) v, H    }  0 R/ a# b5 t' s& h' s
}
; n& ^8 m8 `( s0 X; r. I2 ~( i+ P$ k* u' B. i; M8 s) L# x
// Called during USBD_Initialize to initialize the USB HID class instance.
2 _8 a: i8 K4 P. L  ]3 tvoid DAP_FIFO_Init(void)6 {1 j+ e  l* Y- l8 f1 u
{) @$ Q  M+ c) g5 {" }
    // Initialize variables
* Y  o  b3 f! ~! x; S; t    USB_RequestIndexI  = 0U;
, v8 |- q2 C1 r, A7 w    USB_RequestIndexO  = 0U;2 M% H; t* b' T
    USB_RequestCountI  = 0U;
* s; A/ ^5 M& f0 c7 d3 w$ Y    USB_RequestCountO  = 0U;
, l, u0 h+ K7 v6 k! v    USB_ResponseIndexI = 0U;
0 t1 }# @2 f2 ]& Q2 M$ B1 k    USB_ResponseIndexO = 0U;
; _. A6 u% Y# ^, g, N4 G    USB_ResponseCountI = 0U;8 y# B5 d, @, u& Q1 b6 v
    USB_ResponseCountO = 0U;' m. U8 t' a* `
    USB_ResponseIdle   = 1U;" U1 C+ }9 C. r( m, a
    USB_EventFlags     = 0U;' i- w5 F0 p; e& {; Q( h
}
8 o' U" i% Y( F4 M7 |9 h! v/ N; \/ u( x# {3 x  N
uint8_t DAP_Thread (void) {+ K  t$ z) o5 n- f  K$ v
  uint32_t flags;
0 I: p) a, m) Z: @! a  uint32_t n;
" c) T. f7 Y+ s5 y9 \
) m) B( {- Y# V) f- E  //for (;;) {2 w, D2 H% M) F6 {
  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);0 ?5 m5 R2 D0 R+ ~& P5 s4 `0 I8 R
                if((USB_EventFlags & 0x81) == 0)
" ]) N2 E, ?% L" h4 k6 D                {& r7 V6 g4 H- \
                        return 0;
1 M. C# F( r6 O, l! Z                }7 z: {" x0 q9 g) Q
                USB_EventFlags &= (~0X81);( m$ y/ D7 g  r! h9 s! o
               
3 E9 C+ q& q3 y# C( D, f) u) q                                        9 r! }- w* h" Z( w
    // Process pending requests$ n+ z5 L$ x1 G8 A8 C! c
    while (USB_RequestCountI != USB_RequestCountO) {# `- Q: C* L  G( U
                //if (USB_RequestCountI != USB_RequestCountO) {( a6 j+ Y$ B, j
      // Handle Queue Commands) W  G% E: s2 Y
      n = USB_RequestIndexO;
9 Y- ~4 ]; S2 X2 ^; H$ f6 C( q4 c: U7 _, T$ s      while (USB_Request[n][0] == ID_DAP_QueueCommands) {4 q0 ?; n9 t, q, s# ^& @
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
) z6 w* T* S' u7 E9 p) P) @- g        USB_Request[n][0] = ID_DAP_ExecuteCommands;2 n9 V( N  I" t( D) e  b  }6 Z
        n++;  |) {8 S1 X  s9 O( G! M
        if (n == DAP_PACKET_COUNT) {. z* S& c: @* n6 r9 p
          n = 0U;8 k8 t) ~0 n' `2 v
        }
6 c% X4 c' W. [6 h4 ?        if (n == USB_RequestIndexI) {" X. H1 g1 I9 n1 \) X
          flags = USB_EventFlags;
- S* b* C$ R4 K) E7 T7 r& p          if (flags & 0x80U) {9 P5 O" r& u: i1 x; q5 @
            break;
5 o) S& u8 D: N3 X2 W' f. F          }
, `+ M0 j- w" q- e8 V  n        }7 r  w& ?4 z  I/ |
      }( f4 E! j$ u2 L2 c% ^' Y

- ~! |/ N, [& L! z" Z0 g      // Execute DAP Command (process request and prepare response)
0 O% q2 `" h) N. w$ C7 ^, {# q( s7 _      USB_RespSize[USB_ResponseIndexI] =  Y7 q* a0 P) G0 G2 D$ _* Q1 F& k6 K
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);4 f2 J/ P! P0 i" V  V" O

9 z3 {* g5 a  A      // Update Request Index and Count1 X- y0 s+ o- {% g7 i" Y3 S
      USB_RequestIndexO++;& O1 s& x7 E" q2 P7 H6 g9 L* `
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {! b0 A- `6 y! y* j& J* E
        USB_RequestIndexO = 0U;4 o3 V  I8 n) p8 L( }3 M; n
      }# ~2 M% j) b0 i  H7 D! ]% @6 k0 B- I7 T
      USB_RequestCountO++;
7 f- r7 F5 Q2 o% C  u9 @, k% N, A# l4 `
      if (USB_RequestIdle) {/ b! U. v) N$ _9 A' X
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {" e) a9 _# k4 v- d2 u' d
          USB_RequestIdle = 0U;2 T: x/ ]  o. d
          SetEPRxStatus(ENDP1, EP_RX_VALID);
- i6 N* _- p9 f$ z; j' m        }4 P& `+ E  t- z7 c
      }! w+ _; h& U2 Y5 d9 R# f5 m
; \' t3 v  n4 `' k+ ]; v  F) y
      // Update Response Index and Count
& X3 j- y$ O' G  N' J: q# ]% {      USB_ResponseIndexI++;, A! ^; L- z2 c
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
  z! @6 E6 x5 i3 X, A6 ~        USB_ResponseIndexI = 0U;6 I/ @  F2 U# z  O
      }" e' F! I0 s  E& z' I
      USB_ResponseCountI++;
9 J* B. r6 H9 ~) V( p: Y
% k- |3 M1 ~7 E, c      if (USB_ResponseIdle) {
0 ^& h- |! _; @9 O, }        if (USB_ResponseCountI != USB_ResponseCountO) {! O4 D* b' @8 x
          // Load data from response buffer to be sent back! t& A: v: u$ S0 J. p+ ?
          n = USB_ResponseIndexO++;
) A" x6 t: R; F8 Q' F/ w% e4 n          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {, K+ w6 M% B1 k# x
            USB_ResponseIndexO = 0U;
! r9 d" @* h) f$ O* _          }; k, p6 |  K3 ^% Q* m) I7 q
          USB_ResponseCountO++;( A9 N$ M0 y+ q. f
          USB_ResponseIdle = 0U;
( ?. \, F: E3 J' q2 ^8 w3 q          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);7 R$ l- t+ F/ ]. |
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);$ ^$ J: |, E6 w( w& n% r( M
                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
' A0 l: O  f5 I. [9 q( u0 Z) f, s                                        SetEPTxValid(ENDP1);& h9 C, ?, n* l+ U3 V% {# Z- q
        }
5 a) a0 }- w, B1 j$ `4 e- }; x      }; n# `* p: s4 Y- F
    }
* }- U* f- s+ g$ @  Y5 D1 a- h        return 0;
9 Q6 Z6 A$ z- f6 v  f' }# p' y! }}
* I; X7 s+ v. \5 N; A$ T+ r2 u( V) v# c8 X& Y1 y
// SWO Data Queue Transfer
( \4 ~& ^+ Q& W  q3 O//   buf:    pointer to buffer with data
- t$ s6 u: F, R9 u//   num:    number of bytes to transfer
! Q% n; M% ?6 u0 Ivoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
% L5 X0 M% I: k; u4 ?- R  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
* |6 }3 S" x. j8 F4 G        uint32_t a;
& R- C; @) ?* N3 Z+ U  J) N/ j        $ o- t. t! D% e9 _1 C
        if(num>64)
* _& [1 Z8 e5 S& q% C        {
& v3 Q/ V' G* Q0 J                a=64;  j2 |0 c& p: r, X
                TX_n=num-64;( T* j& D( N% F4 Q% {7 B' g
                pbuf=buf;2 Q, [3 L. ^: ?4 D! K, M; `

) {' Q8 _$ _" `  Q+ u0 O$ Z: y5 D        }else {
$ t7 `+ u& \' N  V3 m6 I. B                a=num;$ R* Y: A1 y" {0 n
                TX_n=0;
, }" t$ g" ~/ D2 w        }  ~  `; C, Q. b* G3 [& t
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);: n; |& ]7 S# a% n/ x! i
        SetEPTxCount(ENDP2,a);
, d+ k. z7 K; m5 u  q8 f        SetEPTxValid(ENDP2);
% ^: L8 }3 Q* T}7 k) U1 x" p; W3 e( J- g5 n) Z

( D9 r. L7 H- f4 F  ]6 T; ]// SWO Data Abort Transfer$ M( U' o+ f+ @- A. t2 P# i# s, a
void SWO_AbortTransfer (void) {
( I( ?* A. N  R6 Y% v  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));" V# D. {9 @; a- P- ^
        //SetEPTxStatus(ENDP2, EP_TX_NAK);" \. W2 h: I% O3 T$ U% W. d
        SetEPTxStatus(ENDP2, EP_TX_DIS);
6 h* [! t9 n0 Z6 _8 W. Y1 _        SetEPTxCount(ENDP2,0);
& n. c! M$ O) ^) ]6 c        //TX_n=0;
; V& x4 E. E- b% s7 R}. A* g: N6 B1 i* [  G1 i9 n
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
- w! f0 f* y' {2 C* m% k8 T/ r9 }* z+ f! L
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处
( P6 u2 g' h; B5 o6 `DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了/ R! n* r  ^+ k
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {: a+ a. S; Z* Y6 S! \: p1 e
  return (DWT->CYCCNT);9 D# b2 e  N. X/ ~: u6 h8 {
}
: j- n5 L+ W% Q* G- u* R8 W0 }" X5 \/ L
void DWT_Init(void)4 h$ {) p6 q6 j% s
{- [# g$ _" s7 u: e+ h  L
    /* 使能DWT外设 */- t% T! w& V' v
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
) A) m0 p3 y8 l  Y3 S5 |, H+ q+ O# u9 h/ l: R! \1 u
    /* DWT CYCCNT寄存器计数清0 */: G5 f% N& s0 ?
    DWT->CYCCNT = (uint32_t)0u;% Z0 a# n( ~0 U8 N

# z  {) u: ]! \; K2 J( J    /* 使能Cortex-M DWT CYCCNT寄存器 */1 t/ ~/ D3 R8 e1 t2 E4 r% ^- Q' `
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
( Y3 V8 t: \8 y}
6 G9 F/ n$ [: Q1 R" l9 ?        
" y! ~+ k( R4 V  q4 ?+ X5 A
' e8 W7 o; X- f7 }5 r然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率: z/ f/ Z; E3 ~- K  ?6 a; d
8 q1 j# Y9 _1 O# F9 T. x" P
然后改为使用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不香么?
! h, N: d- f" Y声明这个变量static volatile uint32_t SWO_EventFlags=0;( l0 o1 T/ \2 B/ ^
在SWO里每一处调用osThreadFlagsSet的地方都改为如:0 V4 _7 J! _2 ]5 ^1 g
//osThreadFlagsSet(SWO_ThreadId, 1U);
& f  e& V6 m' T, }% LSWO_EventFlags = 1U;0 O& k+ G- {) E/ _% p7 w$ n
8 b, t6 H, B1 c/ f4 D* I) x

! t3 Q: A! a; z  `# w- c// SWO Thread
/ R3 ^& b0 m; J, R- D2 i5 x6 }/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
2 A) S  s' O2 w0 m0 l* z: H  //uint32_t timeout;
' q" G4 ]( j$ L* d. t% I5 x. w, a- a  uint32_t flags;1 G  D$ [0 w( k( R% H% O
  uint32_t count;
! H- q3 B2 _; v- F: W, d  uint32_t index;# g2 p1 M- Y: p9 l
  uint32_t i, n;
" q( n. g2 W8 y  //(void)   argument;6 D7 N  N  M. A2 z6 `+ D$ a

. l, F/ Y2 J7 ^' m6 _- }1 F  //timeout = osWaitForever;) g5 D3 P5 G  `, m1 O& L! i

5 S. i4 Q* N! m; f  i; c; j  //for (;;) {
: A& B+ |5 h4 V) d    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);, R- U. H: c4 F; X: q1 V" X+ z# G
                if((SWO_EventFlags & 0x01)==0)return 0;2 s- y! L. m; s' L
         9 ^' ]( y$ L. w5 O6 U& D. j# B. X( t
                flags = SWO_EventFlags;
7 X, L7 e, i1 k( ~! G                SWO_EventFlags = 0U; - o( L$ T5 @9 q) s3 T8 F, j& R, C* g
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {5 r8 f. [- B; H; c1 ~, o
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子) T5 M8 m; G( _3 X9 n& A
                        ;  P: l) l' c  ~% e  m/ u
    } else {
8 a3 u1 l) i9 J1 ~      //timeout = osWaitForever;
5 D6 F/ B: Q' V; i7 ]- l/ J( a      flags   = osFlagsErrorTimeout;
( n! k. N( O/ k- {4 h    }; w( Z7 y+ G5 P( \" N
    if (TransferBusy == 0U) {
" U' m( q2 a6 M      count = GetTraceCount();  G4 L9 J+ h. ?
      if (count != 0U) {
- X. e, I2 o! l) R& H; j        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
6 _0 u  N7 j6 K% O. V1 z  _        n = SWO_BUFFER_SIZE - index;
+ Y, z% D( |6 A; e; H        if (count > n) {
( j) {# y: ?) w: P          count = n;9 @+ i% ], M, O( F% ?
                                        9 D8 s+ G; @' t" z5 R
        }! A; ^) P9 S7 \9 {) S) j; K  V0 J
                                if(count>USB_BLOCK_SIZE). `% T$ n3 I8 J% }
                                        count=USB_BLOCK_SIZE;
* L9 L  O. ~" D* E# t        if (flags != osFlagsErrorTimeout) {
8 Z" q. n9 W! p; W          i = index & (USB_BLOCK_SIZE - 1U);
/ R) m8 N& _4 @  V( ~- o( J          if (i == 0U) {$ ]& p2 H3 J4 V# I/ A
            count &= ~(USB_BLOCK_SIZE - 1U);9 O0 g. {) h! G! n: m- C( f; n
          } else {
% }" [  S: r2 M" r            n = USB_BLOCK_SIZE - i;& |6 m8 M* U" X8 P8 o
            if (count >= n) {0 W3 ?% @9 J( e9 \# B! W, V( t
              count = n;& C, D% V5 x& u' b* B
            } else {
/ t0 ~1 _; K% e( s4 j1 Z; j+ ~              count = 0U;2 ^& c7 p8 U. K* W% V9 D; L
            }" P; ?! E3 E- T: A1 P5 j
          }
9 Z6 B! g# x! z/ z' b2 o6 I' c        }
; R( G2 B* p8 m, d        if (count != 0U) {
# i; z$ ?4 V5 t- A2 f6 v          TransferSize = count;+ d, h- Z! @( [( ]9 {
          TransferBusy = 1U;
) x8 X4 {" ~1 n) F2 a* C          SWO_QueueTransfer(&TraceBuf[index], count);
% \/ p" @7 t" ]* z        }
; K. v# \$ {6 _      }
) Z; Z0 p7 u: f& J. b. L0 h4 z0 a/ D    }
/ y, S( _: |! j' }) r  //}
% y- ^3 X' S4 ^' l                return 0;
; G* D: A% r+ T; n}
% l% b9 Y( i8 Q5 G2 [' }/ [" P) C利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
3 J4 ?  i- R, m#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).5 \; s2 v* K4 ^) w# n
static volatile uint32_t SWO_EventFlags=0;+ ^0 j& a" M; i* R
static volatile uint32_t timeout=osWaitForever;" B* K" t; `7 M2 o$ ^! ?* |" Q3 A+ U
static volatile uint32_t timeWait;
3 {8 o( ]9 {- E, f/ g: Z! \函数改为这样
& a! s% z5 [" d! c7 M! G6 `, I/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {2 q% w$ w4 a$ B3 i7 f7 c9 V5 i- X' r
  //uint32_t timeout;
9 I: ^* z2 V' Y0 }; _2 r8 n  uint32_t flags;2 h8 ]+ T5 |4 ?9 ~- I
  uint32_t count;; m; U8 j5 ?, _5 f
  uint32_t index;7 y$ S; A% P, |1 l& w
  uint32_t i, n;
' F# l  A& V* z  //(void)   argument;5 k# f" [3 o8 @! ]2 Y! z" x5 n/ i) g
  j" ~( r1 H4 P4 A5 Y6 K
  //timeout = osWaitForever;
* |( p" e: {+ d; o( R: _
  B4 p" T- M, ]  //for (;;) {
, Z  L- P- p# M. z2 @    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);' b2 T; m% p  A$ Z0 f% S: A6 r
                if((SWO_EventFlags & 0x01)==0)
! G5 f& _! l" z                {
1 ^$ o- W- _+ `/ y                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
5 z/ U' e, G) C' Q8 C4 |+ C                        return 0;2 A, V6 l+ O, F& B4 ?
                        ; R$ f  U* N/ F1 ^( a) ?) G. B
                }
+ v; W$ r/ |1 s9 Q& E2 z         
0 u. h& ]* a2 ~, E. ]! ~                flags = SWO_EventFlags;
5 F/ m* S( F# X/ I                SWO_EventFlags = 0U; 5 D( W. M( Z/ d4 _* E- O' I6 x0 l) S
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
, I2 w+ n3 X. j( a% @( b# I3 _* E      timeout = SWO_STREAM_TIMEOUT;
' g" W6 ~; F! M! f" V" E% H- r      timeWait=DWT->CYCCNT;
7 n1 N, U# q, Z3 p8 ?7 A0 ^1 d, R    } else {/ ]! m& Z! N) Q; @: W& ]
      timeout = osWaitForever;
! H6 X4 b: f- n5 j      flags   = osFlagsErrorTimeout;
/ X0 f6 b5 E5 U    }
# N+ C" v; a( p" H: `- I& O; h    if (TransferBusy == 0U) {
0 M+ t( H4 _7 {      count = GetTraceCount();1 P/ H6 D9 Z. M0 ]* o
      if (count != 0U) {" H/ W) L4 b& N5 z% U. l& U- ]; m
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);  ~% d" Z: y* |' N
        n = SWO_BUFFER_SIZE - index;
) u4 u1 A/ ?. [8 q        if (count > n) {) T8 e+ K& p0 C- ]
          count = n;4 k% x% S/ J+ r2 W, U
                                       
+ c! Q, G+ [% c1 y        }
2 x% U: o2 Z$ s  `! ~" C                                if(count>USB_BLOCK_SIZE)
- @8 H0 f* `. M9 Z1 I6 t                                        count=USB_BLOCK_SIZE;
) {5 z7 Y# d5 C, r. s        if (flags != osFlagsErrorTimeout) {0 p9 ^  {/ U+ R( x, o5 m" T2 b7 `# I
          i = index & (USB_BLOCK_SIZE - 1U);; |: {9 [" _9 L9 o9 T$ L3 z
          if (i == 0U) {
3 ]! r2 T$ a. Q" g& O4 p; k1 |            count &= ~(USB_BLOCK_SIZE - 1U);6 j3 I, e+ B0 O5 I7 Q2 l: v
          } else {
) Z: d: |# U: h' Z2 C            n = USB_BLOCK_SIZE - i;
# {) k5 C4 a. x            if (count >= n) {9 `& I9 K3 x0 [' b4 @
              count = n;/ O8 m+ n+ D. [( ?
            } else {$ f1 L/ C1 W$ K" m9 L* z
              count = 0U;7 b  E, ^' ~, G2 E
            }
% A+ w: X1 _8 C4 f          }
( t: s; D# F0 K" X. r' }& R        }6 c$ q1 m+ H# w6 m9 {& p
        if (count != 0U) {3 R* ~8 t8 n: J: S: @, ^
          TransferSize = count;* r& d& ?, ^5 ^7 J5 f! `
          TransferBusy = 1U;. ?5 F( u, o# |3 D, t1 s1 j
          SWO_QueueTransfer(&TraceBuf[index], count);
( t* f  M9 [8 Z0 @, {7 }        }
  s/ q4 G( T# F7 U      }
6 J' _/ W* T; t. {' d0 E    }) w- N( i+ Z# _, R: [
  //}
5 Y- X2 T+ s' S1 T9 E9 e  `3 [                return 0;9 N" e2 Q2 }" C. ]/ E. G
}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了! o% {3 e9 A: o- f, G' I
1 m7 f( Q+ x% X: H6 `
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,少了这个等待时间,能增加端点的传输速率
4 _( p: B2 `9 {. K6 t5 C
4 x1 m: X, o( v7 @: ?1 n+ o
+ X# Y0 O/ }. j8 s% u; S' hint main(void)7 k6 ]% q( H5 w' N4 e7 x$ s4 p
{
  Q8 Q! M  p3 z/ l' F% p. y  DWT_Init();5 @/ r& c, V# ^  T( o
        DAP_Setup();
- ?6 r  `8 m/ m' P; A! a  USB_Interrupts_Config();
$ e7 u% c7 F  y" @! d7 ?, Z$ S: ~  Set_USBClock();
6 L8 B; T( a& S8 N  USB_Init();
& n1 V2 U: T7 K        //TIM3_Init(35999,0);
3 X) j" u5 S: E/ f" `        //TIM_Cmd(TIM3,ENABLE);
$ M% B# Q) F! S        
" ^  [  G. p- c4 O* w6 N. y! q        # _% }) h0 [% }) D
  while (1). P" G3 Y( h5 i) T' j
  {* R" {! q- S) ~( e% k7 Q9 ?+ {
                DAP_Thread();
0 D+ y0 G* k" R                #if (SWO_STREAM != 0)
5 l) \8 W# [+ s( i  [                SWO_Thread();
9 y$ C; i% F7 a$ V' ~! x. C                #endif; t7 ^/ `7 }  b- {/ B
  }
+ b8 @: g, t0 K7 v& b% \}- x# w" H8 m& \/ @, v
6 G" t3 o/ r3 L. x
对于DAP_config.h的IO配置我是这样弄的. G4 f% f# g; G) B0 ?
///@}7 U2 T7 y0 F% }2 K2 V% h
// Debug Port I/O Pins
1 d2 f& j- @8 p& D  U1 O4 A  O* E% B5 ]+ D
// SWCLK/TCK Pin                GPIOA[6]/ e) K  H5 Q( s, U6 L
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198* }4 [4 v2 C0 \  n% C' x$ \3 v
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118! p3 T( ?# A/ E+ E6 G: K' A) N
# x7 V2 q1 w  Y7 p# T1 L6 |
// SWDIO/TMS Pin                GPIOA[7]
% Z: p& Q6 F+ n/ e#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
! L/ c0 |  K: h! v8 ^0 {#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C
' i2 R. q3 P% H  x) @4 s7 `1 x( O' k
// SWDIO Output Enable Pin      GPIOA[7]
) q: q/ \+ e  M* ?& r2 ]#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
5 d( a% U  L9 \3 R                                                                                                                                *(uint32_t*)0x42210070 = 1; \9 w% _' ^! |& m% }$ Z5 Z
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
& Q4 C3 n* u9 A1 Y                                                                                                                                *(uint32_t*)0x42210078 = 0; \
+ T( N& N2 K0 x6 [                                                                                                                                *(uint32_t*)0x4221007C = 0;}
% Y" Y  U+ Y8 I* T( i  D" E9 s
, h+ o. w+ D& n/ G1 G' Q#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
7 D  n; n" ~. B& e- _                                                                                                                                *(uint32_t*)0x42210070 = 0; \' e2 W5 {1 ^, D* R; ~. V! u6 R$ X
                                                                                                                                *(uint32_t*)0x42210074 = 0; \  o( Y4 j& \! ?4 F- @
                                                                                                                                *(uint32_t*)0x42210078 = 0; \! D& _9 [* x( ]9 Y+ z
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
( ?' @  {+ R0 g8 J3 t6 |! C2 z9 r% Y; r; k
// TDI Pin                      GPIOA[8]
( M, U0 k* s$ T+ f6 c) v#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
7 j4 U2 M5 w% W, ?# C6 [; T3 u+ h  Y#define TDI_IN                                     *(volatile uint32_t*)0x42210120; a% V( x% o  p: K) J' n( l

1 T) a$ o/ Y+ ?# l  E// TDO Pin                      GPIOA[10]
7 m4 d& A9 b7 @) A6 Q) Y/ [#define TDO_OUT                                    *(volatile uint32_t*)0x422101A89 F( e  }! X2 O  ~
#define TDO_IN                                     *(volatile uint32_t*)0x42210128
7 p* i& _, W$ D7 w" ~4 t
0 R" R/ U7 O- p4 [3 K// nTRST Pin                    GPIOB[3]2 h: A6 c* S/ B; H9 W$ V
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
4 Y' m- y8 b8 r9 Q$ S' ~#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C. E* p( A% @3 S" a) ?7 z. _& Y

9 M7 N" a# [! h$ N; p# }// nRESET Pin                   GPIOB[4]
8 ?+ P; j+ n: A" A1 D/ ~, i! j#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190& B! M- X( f7 ]" o) R
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
: F0 p: Z( S) R+ V$ O% y/ L4 ]1 h) u% T2 }0 g
// nRESET Output Enable Pin     GPIOB[4]1 v8 p2 F9 N( j* }9 h8 U( x
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
) {! I' @. |: e                                                                                                                                *(uint32_t*)0x42218040 = 1; \/ n1 \1 Q# O3 y* c1 r- N9 _. q
                                                                                                                                *(uint32_t*)0x42218044 = 1; \0 h4 y; h% z9 V% C# `/ Z
                                                                                                                                *(uint32_t*)0x42218048 = 0; \& Q2 j3 ]4 F) \: r6 C
                                                                                                                                *(uint32_t*)0x4221804C = 0; }
( P0 K) b1 j0 m! B8 }6 ]' ^9 }; C* w$ _* S) N# Q/ J
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
! d( m0 n9 u3 p                                                                                                                                *(uint32_t*)0x42218040 = 0; \4 M2 X* k& f. Y5 U# L" \: v& ^
                                                                                                                                *(uint32_t*)0x42218044 = 0; \, [  @- ?& Q( }. B, c: r
                                                                                                                                *(uint32_t*)0x42218048 = 0;\/ A* [  Z; d# Q# D! r# K
                                                                                                                                *(uint32_t*)0x4221804C = 1; }$ ~2 y0 m$ ^+ O( g4 P

0 S0 l# c* W5 H3 Z9 l& g# n! _0 Y* L3 B! S4 c, s1 U0 U3 u6 g
// Debug Unit LEDs
- Q3 x4 A0 x, c' t5 Q3 g( w" o) m" ^% ^
// Connected LED                GPIOC[13]
( _7 @  e$ l: y+ y- \% W: E& p$ |#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
) i% t7 f3 M, N6 k2 s, B#define LED_IN                                                       *(volatile uint32_t*)0x42220134  p# t' F& A/ |6 w' G3 T/ e) A2 M4 `
' U9 n( ^( q1 x: U, X9 w
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \7 o) k, l  |5 K( ~) n
                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
; o5 N/ P2 E! Z3 {                                                                                                                                *(uint32_t*)0x422200D4 = 0; \7 x4 c8 k- [/ _$ r9 O6 {3 M
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
" ?' x7 y) p& \. R7 y0 K                                                                                                                                *(uint32_t*)0x422200DC = 1; }( _' R0 t3 B0 k
// Target Running LED           Not available
* W' Q4 ?. E- }! J* t- Z- A5 t4 s; m" f
// SWCLK/TCK I/O pin -------------------------------------! D7 X% ]) t- M. n8 V

* c8 f& ?/ O$ L5 G: a' n3 h6 _/** SWCLK/TCK I/O pin: Get Input.0 E( s! \0 c8 W1 @6 Q+ \
\return Current status of the SWCLK/TCK DAP hardware I/O pin." }0 Z. i" U3 D" u
*/
$ |, ]7 [$ e/ {) o8 |, ~__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {: C% {* R. W4 G6 h
  return (SWCLK_TCK_IN);
1 J$ W1 f! m( w# s$ m}2 M6 t# @  X. F  x% G! W

/ \/ a! [! y7 m* k$ P( V/** SWCLK/TCK I/O pin: Set Output to High., q: Q, _6 r. w) O. I
Set the SWCLK/TCK DAP hardware I/O pin to high level.% Q5 w" ^  o5 L4 m" X
*/
' b% L" U. W, Q4 L__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {+ H9 s6 N! K  c( g' u- G
  SWCLK_TCK_OUT = 1;
$ o& O# K9 |. D7 y; ?/ t( L}2 q; ~+ n4 Y' }" R6 r
/ \* p) R9 B: ^& H
/** SWCLK/TCK I/O pin: Set Output to Low.8 j1 Y5 Q$ w  U$ k1 j" g- W
Set the SWCLK/TCK DAP hardware I/O pin to low level.1 P  Y" }0 p: X& [' [
*/
3 @& t1 P5 F/ h$ x# S__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
5 l( p  ?5 ^# D6 t! \$ @  SWCLK_TCK_OUT = 0;1 Q# H8 w3 T7 ?9 v6 C5 A
}
; V2 a) @! \3 F; Z- ~& m+ Z! e4 ?

* j1 R7 W7 O0 E5 s/ k// SWDIO/TMS Pin I/O --------------------------------------
( H5 L3 c4 h" o& C4 N+ H7 P
$ |4 R( d! T! d' k/** SWDIO/TMS I/O pin: Get Input.5 b; r. U+ z& c" o" O( Z& B1 p
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
9 Y/ j: u  l* J3 i*/
: i' u# P( y' B2 G__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {) G. ~  \2 S2 o$ M. b, X
  return (SWDIO_TMS_IN);
' _. U% n! u& _, n& v6 z# K9 \}
+ J' f# x% S% O7 U  `9 m" F1 Z  h$ {$ S4 ^( f; [) c
/** SWDIO/TMS I/O pin: Set Output to High.
& Q7 z3 W& p* F1 l1 e8 ~Set the SWDIO/TMS DAP hardware I/O pin to high level.: t5 E; X$ ~1 ^: F& N8 Y% y4 ~
*/) V1 l; K1 n( O6 O, s
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {
" |4 A( ~8 E' P1 n1 B- [. L  SWDIO_TMS_OUT = 1;9 H" C# S' [- r+ l$ s+ e. `
}" v) k" Z8 v8 |- u' ~
3 X! g8 l. W( \7 ~6 M2 B
/** SWDIO/TMS I/O pin: Set Output to Low.
. Q; Q+ m9 X! }7 xSet the SWDIO/TMS DAP hardware I/O pin to low level.
0 ]. D+ r, @! z*/
( ], |# v" D6 r/ u& D4 @__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {
, V; m+ B! m* X" X7 D( t' S) O, ~  SWDIO_TMS_OUT = 0;( p9 G8 M5 U1 R* B) u- Y) k" J
}0 _/ I  w" o$ }8 ^3 T
0 o) o4 U: h( [  v1 X
/** SWDIO I/O pin: Get Input (used in SWD mode only).' z1 |4 k, H0 N1 s# g8 d
\return Current status of the SWDIO DAP hardware I/O pin.
7 d. `1 [  H( s* M*/5 K! R4 @% \* K. o# s
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
1 y. |. ?- v1 n5 m/ z# N: p  return (SWDIO_TMS_IN);5 W* p+ H& H; O
}1 S0 m9 J3 e& Q

/ f9 `" f7 G2 _9 R/** SWDIO I/O pin: Set Output (used in SWD mode only).
" n8 d; U5 v1 p) X0 U\param bit Output value for the SWDIO DAP hardware I/O pin.3 a9 Q: s$ k1 ?8 i/ v9 P8 ~& d5 P6 N# c
*/
, j0 P% `" I- f__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {, E: f* R0 X. u  S
  SWDIO_TMS_OUT = bit;
/ o9 Q, ]* Z( [" u- q}
1 ^9 Y8 c! r/ E7 E  V. O* x  c" z
6 |4 ^' |+ ]" y) q/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
4 I3 t, l& V# {7 t( HConfigure the SWDIO DAP hardware I/O pin to output mode. This function is
9 {4 j- R! k1 F; I8 n) `) gcalled prior \ref PIN_SWDIO_OUT function calls." v" e5 a9 [, k7 b/ P9 U
*/& h+ v% r: ?! @; \, b* c
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {3 G/ V% @! k5 d; _# H
  SWDIO_Output();; r5 E. b, o# I+ }/ x2 O
}
) y) F8 Q/ z: ?5 [4 G  Z' O; [7 w7 c3 F' n* k; V% T4 [4 }% I
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
# y% A7 q4 M# Z6 t1 e( IConfigure the SWDIO DAP hardware I/O pin to input mode. This function is) R8 \; K( \  o* H
called prior \ref PIN_SWDIO_IN function calls.3 [# f- ^: r$ Z( b9 d7 z" {6 E
*/
3 {, [4 g# n# ___STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
7 l) R# I5 }4 z2 q  SWDIO_Input();
# R( r, s- Q5 T4 y  _) T}, y$ l9 y4 A5 @/ C3 [

! i- }4 R% U: C" f+ ~楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
& c5 L+ q5 y/ J; E$ ^/ H即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下- T5 }5 x1 a  w+ `: {
半-- 回答时间:2024-6-28 11:27:16

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

所属标签

相似分享

官网相关资源

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