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

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

[复制链接]
radio2radio 发布时间:2018-5-31 15:47
阅读主题, 点击返回1楼
1 收藏 45 评论417 发布时间:2018-5-31 15:47
417个回答
ljlt 回答时间:2020-12-7 10:04:09
感谢分享,不错。
冬天ア之釜 回答时间:2021-1-8 14:10:55
看起来真的很不错
huawuqiu 回答时间:2021-1-11 17:04:57
感谢LZ分享~~~
ricklou 回答时间:2021-1-25 10:50:25
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduino ide),stm32好像有联络信号pa0和pa1,希望做一个,让复位时给一个低电平复位信号。
6 s+ U( L" D) y  g# J- T9 c
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
3 t  s5 |0 `( G. q除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
. |9 B' Z$ Y$ @3 w2 f7 ?$ }3 b
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
, j# K" ]5 r* Z8 d# C2 S7 a- u7 G/ ?. t2 u, v1 ~. C, v
软件复位是另外一种情况,需要向目标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. \( u9 w4 I: }1 H
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...

0 W. N4 g4 V' o4 f+ d9 L! CnRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。6 f( W- \' A' g. L( ?% T
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。5 Q. r+ Z7 k0 i  _# o  v$ w5 k

& q5 d5 t# R6 G" T/ }你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。 . ^& n- w  O% y4 m$ [
或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。% K! O- p! D, H! O+ c0 u

# y. |0 J. C5 ^# |! M
; j1 ?( |* b9 ^/ p% V- Z1 J3 |
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?  o+ j% \( M6 v; b: w& `
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap 3 D: ^/ T: I' G; t7 p6 ?; f5 y  ^7 b
起点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系统,轮询执行
1 z( H( {& `/ H; j0 @/**1 u+ H+ V9 g+ X
  ******************************************************************************
, N3 e# h2 C$ B1 E2 N  * @file    usb_endp.c$ z* F: Q5 s2 z* t  a* d( q
  * @author  MCD Application Team* ~8 w7 f) k9 ~" f0 p) r
  * @version V4.1.0
, Y1 S; Y, x; X% A& x1 e- c, e  * @date    26-May-2017
, T$ I  p* p" s/ M1 K  * @brief   Endpoint routines
& e, }6 {: I* ~! S8 p7 \3 M' K  ******************************************************************************
( G0 I7 s- A1 w, G4 ^& [# D  * @attention4 f* Q% U$ K! y& ~7 Z# `# m! B
  *
4 f+ O* q  q$ s- p. ?- M  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
0 j, q/ T0 t1 I2 d  *: x; j2 T/ E, Q+ H& I
  * Redistribution and use in source and binary forms, with or without modification,
$ B0 W( `5 J$ W/ m* J* n  * are permitted provided that the following conditions are met:% B" H# }$ r; s, Q1 Q
  *   1. Redistributions of source code must retain the above copyright notice,
' Q4 `9 G1 C! R7 B8 K  *      this list of conditions and the following disclaimer.# @. u' Q( t) ]
  *   2. Redistributions in binary form must reproduce the above copyright notice,2 @: C! |- l7 V- [/ |
  *      this list of conditions and the following disclaimer in the documentation
+ T" ~& _- m, [$ N4 q  *      and/or other materials provided with the distribution.
3 Z5 p5 }8 j8 ]: w# t( r, ^  *   3. Neither the name of STMicroelectronics nor the names of its contributors
. h& I7 Z, h+ g& }* J. t  *      may be used to endorse or promote products derived from this software
- B9 U5 ^% ~+ e' k  *      without specific prior written permission.
+ F0 a0 X8 ?* Q$ k- I+ _+ C( v4 U+ l4 u  *
) |5 i+ _. t, C, R& I  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"0 M0 Z0 L6 R. V+ \
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! b# v2 B) t$ S, B8 s1 ^6 _  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ }! [. I7 ~% `, D: \1 z  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE1 P( s. u# B5 w/ p
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
" o; v, q. m$ y2 a  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2 B3 r  \- y  n, @' f  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
$ j& q: ], U. o! q4 i; L  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,- p( _- x8 |8 T1 \' r# A1 V
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
& \" A- P2 ~/ D5 q! J4 ]  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" \2 U' C4 t# j! w- N; F; F* Y  t  *
) |+ j4 j, u" `( L1 B  ******************************************************************************
8 B# V) _9 o3 X  */$ n& o) G" U; m5 Z+ j
- s. H3 X; k/ X0 e* d1 N

; ^/ Y  Q3 V' Z- f/* Includes ------------------------------------------------------------------*/
1 s4 R! G6 T7 S9 h8 g#include "hw_config.h"
( h) J3 H$ G! P: V; B" [4 y$ H/ [/ o) X#include "usb_lib.h"
/ a- \3 p+ F$ X' X. z5 V#include "usb_istr.h"6 k. P8 i( U, X7 P
#include "stepper.h"6 [& H) G+ F0 p! ^% A4 I/ c
#include "string.h"
' ?! F* {8 g7 L5 ]0 F0 |
' S$ X0 y% Q5 G0 D! p#include "DAP_config.h"
/ V$ V7 |$ Q* z4 q) E0 S# Y#include "DAP.h"
+ h6 e( A5 N. S+ F
. R6 B7 L9 d  J9 w8 v7 N7 c0 k! n- b9 h9 a% V
/* Private typedef -----------------------------------------------------------*/+ H# r! W  o* Z/ M8 U
/* Private define ------------------------------------------------------------*/
' F1 ~! N. }8 K! W# g/* Private macro -------------------------------------------------------------*/
2 k( Y; r! \9 K& [5 Z. R" l/* Private variables ---------------------------------------------------------*/
7 P+ Q  n7 y# `& ^9 Ustatic volatile uint16_t USB_RequestIndexI;     // Request  Index In
8 W7 N& X9 t7 d1 e; A. D. i( Bstatic volatile uint16_t USB_RequestIndexO;     // Request  Index Out
; B% {( n! I* }# Tstatic volatile uint16_t USB_RequestCountI;     // Request  Count In* I4 d) ]. `6 `( b' z
static volatile uint16_t USB_RequestCountO;     // Request  Count Out+ l% E0 q" c: O# D& h
static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag7 @$ O  k9 W) h  a" E0 `* P! e" ~
! K8 T- H1 p5 d+ x2 Z
static volatile uint16_t USB_ResponseIndexI;    // Response Index In
9 @/ Y7 F. p/ _/ V: e4 w! ystatic volatile uint16_t USB_ResponseIndexO;    // Response Index Out
, `' x0 j2 {+ v/ A5 V' V6 {static volatile uint16_t USB_ResponseCountI;    // Response Count In5 v; a5 e% Y$ Z
static volatile uint16_t USB_ResponseCountO;    // Response Count Out, o$ R4 n+ l1 }+ n( N: ?  K
static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag) Y( s$ J* |& j- R  I4 W6 ^  t" u
static volatile uint32_t USB_EventFlags;
* C% {. n) x  d. n, c, |  V7 D% Y' y- T3 T; w! n$ c: y, U% D) W6 C4 Y
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer( Q" ?0 y' b+ V6 }" o: a" @
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
3 N/ Z* j6 R4 Rstatic uint16_t USB_RespSize[DAP_PACKET_COUNT];* G: K2 y$ b$ B

. ]7 j: r9 @, f  \' N/ A0 e; [/* Private function prototypes -----------------------------------------------*/; `8 H& D' O& W) O4 X$ q; `
/* Private functions ---------------------------------------------------------*/
' A( e  z' y) j/*******************************************************************************0 U$ j6 i+ O5 D! y" ]7 ?
* Function Name  : EP1_OUT_Callback.7 |8 y+ C% J; G/ H: m# i
* Description    : EP1 OUT Callback Routine.
$ k( i0 V" _( a9 F* r9 w- x9 j# ^! i* Input          : None.% a. y3 w; o6 z* }. k
* Output         : None.* F3 N  |: j7 L5 m& l& X
* Return         : None.
7 f$ r) Q5 u9 L6 Z* [$ m*******************************************************************************/. ~5 U' v/ F  x4 c& |: i3 X/ b1 D
void EP1_OUT_Callback(void)( Z& ~2 y# h" [# o- f5 C. }
{. V: h- B- r" m& B
        uint16_t n;- s4 B! p& @; U- ^: I
% c9 A9 j3 @' J" d3 I+ Q4 `& I# O9 s9 r) z
        n = GetEPRxCount(ENDP1);
! n. F+ _* K3 U5 |2 e        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
% r3 o0 Q5 w; C$ b        if(n !=0){
1 v( X3 r/ L7 N7 X' V, ?1 C' {* P                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {9 n# `8 }5 N$ ?: ^5 g: t/ z
                        DAP_TransferAbort = 1U;9 M, {" @5 c) z/ y4 R# }
                } else {
: h6 s) n  H% g. U6 v0 f                        USB_RequestIndexI++;: `  R0 W8 p" o9 A. K: a  K$ x
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
9 |* P7 T1 c  l, ^. T3 A% _' w                                USB_RequestIndexI = 0U;3 w3 M! x7 D1 T' h
      }
! z2 O2 u8 z$ N  u8 M5 }9 N/ w      USB_RequestCountI++;# f& K8 k% D- l& v4 H
        USB_EventFlags = 0x01;
9 v# J/ g6 }: C# m; j6 t! e    }
& L+ u7 V2 J( {9 y) o# J        }        
3 ^  S. p' c) h% [- [        // Start reception of next request packet7 H0 M  j1 @$ i
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {# u5 C* y: c4 N- @( `! _" ~
                SetEPRxStatus(ENDP1, EP_RX_VALID);
/ R; _8 r) n& ^$ F7 N; l# o        } else {
, m, v2 M2 A& ]  v                USB_RequestIdle = 1U;, M" }' S) a" `/ [$ O
        }                        + c7 {* C- x  X7 G& I$ \
}
% A0 j* ^* V" ?2 K2 h- ]- f$ u. u
/ o+ A2 y3 ]- A. A" I( K* W: y4 i/*******************************************************************************/ H4 S4 [9 Q; d
* Function Name  : EP2_OUT_Callback.
8 ~0 P6 x' }8 R$ Q+ |+ ~* Description    : EP2 OUT Callback Routine.+ H. b$ ?2 i5 c7 g; B( _
* Input          : None.8 L7 r% [' w4 f8 _4 \9 t# h
* Output         : None.
7 _' |- y" ?3 H+ O* Return         : None.
* J$ ~. v6 l: ]*******************************************************************************/: V/ j1 q0 L$ Z  k, Y
static volatile uint32_t TX_n;
; J- ]* R$ k; P. a1 Tstatic uint8_t *pbuf;; K. U5 d3 l+ i, S$ Q
void EP2_IN_Callback(void)
" r& B- F4 Z! D# ^! U3 W; i{' D( Q+ Z# Z8 m3 v& D
        uint32_t a;
8 `6 d/ y. Z" Q3 U+ J        if(TX_n>0){8 q6 s/ D' F5 M
                pbuf+=64;
1 x% z* Z/ z8 B& b' q) Z5 R. a                if(TX_n>64){
5 W7 \9 ?$ A; ~5 {* I$ T9 S) g                        a=64;$ D$ ?5 M: {- n- J% M$ l: T
                        TX_n-=64;
( U" a5 C- \# D7 j                        ' h9 `8 u2 \9 q* `+ n
                }else{# o6 c% s( K, a9 I; N9 V
                        a=TX_n;
" L/ f" _- j6 j: |: d" j5 l4 k                        TX_n=0;' ~. T# H/ I' W  y& G( @9 i, ~
                }
) `) N$ c% q, \9 S8 p9 t7 V7 [. N                5 |" {; V: N3 A+ l: B9 ^
        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
6 _, O4 o- L; ~- C( B! [        SetEPTxCount(ENDP2,a);
; g: f, u6 F. I' R, S& \! m                6 Z" u. C  f3 G. z5 S& K
        SetEPTxValid(ENDP2);3 o; U, ]8 v4 ~+ e) I# @
        }else{
* S! A' V9 K2 p+ F4 \5 b                #if (SWO_STREAM != 0); i5 c& Y0 I; `
                SWO_TransferComplete();
+ i3 F9 A4 q  Z                #endif
% l' z3 e# {% O, W        }8 d3 V: N9 s9 j7 e1 w5 q, i
}
$ r3 G2 X  N. M5 p) C
" ~; u3 V' l' w5 q$ |6 I/*******************************************************************************4 t' S8 m0 R- D# e1 ^; S
* Function Name  : EP1_IN_Callback.
  H+ L7 y6 ^0 p* Description    : EP1 IN Callback Routine.
( P: Q' r$ \+ L+ a- n* Y- E/ p* Input          : None.! w3 I7 H" ?- u4 `- H! w* a; h
* Output         : None.
/ |# K3 T2 {9 f( n9 C* Return         : None.
: W. V( y. ^, Z% x*******************************************************************************/- L* |* A9 r" q+ E% D9 `
void EP1_IN_Callback(void)  l$ \, y! n2 N6 K- W* H
{
) \6 t7 Z( E9 }: F$ ]    if (USB_ResponseCountI != USB_ResponseCountO) {4 S' s  ^: p1 ]/ G9 K  S* Q
      // Load data from response buffer to be sent back: M) I! V. y1 M' r( M, p
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
" b/ Y- L: Q6 U9 s' \' P, I& b                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);, A% a0 f- a! B
                        SetEPTxValid(ENDP1);                        
' T2 J! O, a" a- O5 C      USB_ResponseIndexO++;
: R* y* G8 D: l4 i" m( X      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
' p0 y  l' \( b1 U! P% d        USB_ResponseIndexO = 0U;
: T3 j- c# Q; r! f/ H      }
7 z" p* b/ p" N. n      USB_ResponseCountO++;
1 n) C  H4 T' N, T0 o) Q8 y  S    } else {% v: R& q7 s) z! g! u0 O/ F9 U
      USB_ResponseIdle = 1U;2 g* Y& h5 G  h2 W, F
    }  ; a, B9 u8 B1 I" W+ L1 R2 D
}' y- V$ K$ e. C2 H1 _6 f2 ?  M

- ?5 [$ e% c# l9 Y// Called during USBD_Initialize to initialize the USB HID class instance.
0 A# [9 c+ j6 V6 x% E0 Rvoid DAP_FIFO_Init(void)
9 f0 f, \7 O' k0 n{; B# n4 f1 z( x) g- H& D1 n. }
    // Initialize variables& H8 h! N! U2 {
    USB_RequestIndexI  = 0U;
$ C% J+ C7 q+ Z: ?8 [( Z, k" |( v" Q/ _5 p    USB_RequestIndexO  = 0U;
& m: J8 U2 E+ |( x# u+ J* c6 x    USB_RequestCountI  = 0U;( |. ?; A3 n2 P# X) e
    USB_RequestCountO  = 0U;
( F) A6 y& ]2 a: [/ _    USB_ResponseIndexI = 0U;3 }7 ?: d& d, [7 ^
    USB_ResponseIndexO = 0U;
, A" {5 p, i3 {, D. G7 N+ A    USB_ResponseCountI = 0U;
( E8 z' T3 n2 c8 S; s6 J    USB_ResponseCountO = 0U;  u& S- R! H8 l' F
    USB_ResponseIdle   = 1U;
' ~1 t8 N4 E6 o# C  P7 Z    USB_EventFlags     = 0U;
1 c  h+ n" W1 m. n4 i* u, f}
  Y7 ]% s1 T' V7 Y1 Z9 `; V* D8 y8 d  `, Z$ W
uint8_t DAP_Thread (void) {
/ j6 k  b- S+ n, g. n3 ]; m2 `  uint32_t flags;
+ b  E- {9 t6 ]5 D4 t) X8 o3 I  uint32_t n;
$ B, e0 ~* _) C: g
/ O& [) G; P% U* K# N: F  //for (;;) {
/ w8 F. R  h6 I- s& j  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
0 e7 r  Q9 `: @                if((USB_EventFlags & 0x81) == 0)" ~( [: m* e( m8 ~, G: R/ ^
                {" [5 w3 Q) T* Z) ^
                        return 0;- G& E4 \& Q" j5 z- \
                }# Y+ T- g8 D% G8 W
                USB_EventFlags &= (~0X81);
1 @8 e  z& Q: c# n0 D* o% ]' S( c                : B6 g6 }9 v' K5 m" _
                                        . @1 R- D* M8 t/ w2 g
    // Process pending requests0 F. B( m. U7 V9 Z
    while (USB_RequestCountI != USB_RequestCountO) {3 s. _! [2 C" X6 }
                //if (USB_RequestCountI != USB_RequestCountO) {" J5 W' a- ^6 H8 W* S0 O) H4 a
      // Handle Queue Commands
. H7 u1 R1 ?2 X" F; A4 r      n = USB_RequestIndexO;
; B/ @9 x, L- A) f. P# t      while (USB_Request[n][0] == ID_DAP_QueueCommands) {  e( U  P' x7 q2 n
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
9 d. \4 }; o4 V: e        USB_Request[n][0] = ID_DAP_ExecuteCommands;
% Z* m* d5 S4 r" B# r3 g( ^        n++;1 m5 ~7 K* ~6 K
        if (n == DAP_PACKET_COUNT) {4 h# x  X7 y" x- L, \
          n = 0U;
2 q+ N7 Y" O. l        }1 U% g( w+ n9 H+ }9 F  c
        if (n == USB_RequestIndexI) {; ^+ ~+ h- q& V8 N! d' e
          flags = USB_EventFlags;
; J: w+ K& A0 {% ], ?3 q- @+ C          if (flags & 0x80U) {
8 ?* j) [3 r2 q! ]3 {  E8 p            break;
) b9 I# l. i: Y9 A/ Y          }
+ g& l1 b8 O: y8 O        }* T& ]5 i: G& V8 W5 d& l  c
      }
5 {5 _% O0 l) T8 S: d# g% u
2 J% u) K+ y! U, V/ W5 L% y      // Execute DAP Command (process request and prepare response)' I' a" {- a$ ~. `* F5 p$ A# z, ~
      USB_RespSize[USB_ResponseIndexI] =& U4 g2 i% w; B1 a
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
- ~4 `# {# s3 h" `& R
! l; S. m: d! J: _1 _# c6 ^      // Update Request Index and Count1 d3 I$ J9 X  Q! E9 j0 i) `
      USB_RequestIndexO++;
: p0 E+ k( E+ X      if (USB_RequestIndexO == DAP_PACKET_COUNT) {7 u) U. w6 d6 g% A* o$ l
        USB_RequestIndexO = 0U;
5 a: \/ `8 S; b$ i      }% x& g! i( U& S" q
      USB_RequestCountO++;
- G) ?8 {8 C1 |  j0 {; B- h, H$ y7 T
      if (USB_RequestIdle) {
, o2 m9 S7 z5 @        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
7 o! |$ t" m" n+ _& u1 `          USB_RequestIdle = 0U;
6 x" {5 \0 R4 G+ x: M+ Z. a          SetEPRxStatus(ENDP1, EP_RX_VALID);
7 j( ]- h/ z  ~/ j* a        }
5 {- b; ]( R+ ?! h( @0 N' {7 W      }, R, ?- ]/ J) L+ w, c% g
' ~: i' B# K$ @. l9 j
      // Update Response Index and Count
6 B$ J9 i) T9 t; L& D( n# h      USB_ResponseIndexI++;/ o( e* d( E; a4 {5 J, q. p
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
: [% ]0 J; |) m        USB_ResponseIndexI = 0U;9 B# @: H- O2 F. W0 ~  Q
      }
0 \" t: V) u+ i      USB_ResponseCountI++;4 j! `: @7 U9 C2 Y: ?

1 x; e  k! Q/ \+ y8 X: p      if (USB_ResponseIdle) {, [6 `3 b  B0 w
        if (USB_ResponseCountI != USB_ResponseCountO) {. z% w1 g+ m. |3 w6 V! S
          // Load data from response buffer to be sent back" s" K+ [. \# H) D; {: |& X
          n = USB_ResponseIndexO++;& I. h3 f" D4 W, b9 ~' ?! n
          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
4 Y  X9 B6 s+ X& U+ ]0 |# a) E( s9 a" s            USB_ResponseIndexO = 0U;
# I7 k; j& x8 }. j6 M5 \          }! u0 R! G( {6 K# s6 E: M8 T% r
          USB_ResponseCountO++;
# D8 o" f; w0 D% z' A/ E$ N          USB_ResponseIdle = 0U;
& S3 Y; ^0 X; u' T/ O4 v          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);3 c5 l" Q2 w5 Q1 L& l
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
  B0 v# q# N# s& a' p2 J                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
2 p# u  {- a' |9 Q; w3 W; A- q) c0 Z                                        SetEPTxValid(ENDP1);
0 K7 w; ^% |4 i+ M        }& m9 W' I1 N# r5 D
      }+ `; T" T; H, a% C, B) p0 P) z
    }
* K/ W8 ~9 m, q        return 0;
; }: ~; |' S7 p, i4 k9 a+ C}  Y0 c3 R6 }0 {, m- P8 a
: p8 t* {) M4 P! z$ O
// SWO Data Queue Transfer
9 Q& o% S  K; Y- L//   buf:    pointer to buffer with data# a' R. P" C5 p1 n! X9 J
//   num:    number of bytes to transfer# J6 `0 J. y; ~/ h
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {" v! w- B# P# s; L* C
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
. V, Q% r. W& P        uint32_t a;
7 v3 q9 B0 L! c  ]& V2 }) l: O8 r$ q        
; p( B8 n  v! J( V/ T( R        if(num>64)
7 J+ G, @2 h! @7 G+ ?        {0 {, q0 {; ~9 {
                a=64;
# K9 g  b8 l3 S! Z                TX_n=num-64;  {% B% u* W) G) J7 ?
                pbuf=buf;) d* H) L6 A' U) N6 R' h

2 ?* y. D1 x' X. B0 U        }else {( u. ^( e5 O! `$ l: n, Y
                a=num;
$ [4 S# ^% H5 I* H5 T7 V; F                TX_n=0;- Z  [, k3 I8 T$ Z
        }
6 D! p2 P5 K' }- N; n        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);
  t6 V/ ]* Q" C: r! s1 d, N& w7 G        SetEPTxCount(ENDP2,a);& a( z  ^0 s% X9 F
        SetEPTxValid(ENDP2);) T: n" ~1 H6 F
}
, d$ y/ J* L; P: _6 J2 U
8 j- c1 ?8 I% M+ j! Z9 e8 d  I/ H// SWO Data Abort Transfer# m  S+ Q# s) f1 `
void SWO_AbortTransfer (void) {
! I5 G* b3 Y) M4 Z  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
: n1 _- ]0 u' ~' w# M8 F# P        //SetEPTxStatus(ENDP2, EP_TX_NAK);" @+ M+ v- }, Z/ C/ Q2 _# e
        SetEPTxStatus(ENDP2, EP_TX_DIS);
5 t8 t. V+ _* b. X1 }- f' G        SetEPTxCount(ENDP2,0);+ V0 W1 l* T; L, _# U
        //TX_n=0;6 {  m7 ?" |7 ]1 v: k9 [2 m7 q
}0 H# ]. T( p1 X/ q) K
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
$ ]  }% K$ E: I0 Z6 V, N6 v+ k- P
移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处& V: R+ T, w+ D$ x7 t  E$ x1 E
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了% W. u- C7 D- _8 E6 b6 N
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {: @3 N) I- L4 G6 E; X
  return (DWT->CYCCNT);
6 |: l2 t& f2 P, \( V9 O' f}4 p. F; R  i+ G9 m" X
6 n. S1 z3 ~3 }: N) t6 i# o
void DWT_Init(void)
. U0 h/ a5 Y6 M9 B2 h* F- f{
8 Z; W. S9 M6 @' r    /* 使能DWT外设 */9 @7 P2 n1 c) _, u$ |# h( x
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
6 L3 K- K5 C  G1 e0 O4 Q7 Y. m. @" C# F/ C" U
    /* DWT CYCCNT寄存器计数清0 */3 @2 g: V: ^* p7 k' w$ `
    DWT->CYCCNT = (uint32_t)0u;. V. Q' F' q2 ?, O) g' X. c/ p
2 b; k0 l6 e# w% s- J' \6 q: D: j( ^
    /* 使能Cortex-M DWT CYCCNT寄存器 */
. B3 U# D4 m2 f; n) b. M    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
" J2 _" E; r$ `) L5 u0 T}- F" d& \' g2 }# ~! B" W
        " \4 [" I" _4 P, z0 F" {" O
$ O- a9 l$ _& O* W
然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率
( v  d) N( t5 a2 {7 P
) d/ {3 A9 _( U7 [然后改为使用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不香么?
, }: \9 R/ |3 L. M声明这个变量static volatile uint32_t SWO_EventFlags=0;
1 C& c$ Y0 |; O# |9 ^在SWO里每一处调用osThreadFlagsSet的地方都改为如:
- A# Q$ ]+ r9 j//osThreadFlagsSet(SWO_ThreadId, 1U);, t  A* E2 M8 Q8 [
SWO_EventFlags = 1U;, {, ?: H7 D+ k  J

' P0 G5 b' w4 ~1 E7 I
7 V  X: P$ ?$ f$ ]// SWO Thread5 z* F! o: Q6 q/ A6 |$ f) n* a
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {) o$ G) c% A& B
  //uint32_t timeout;
0 D6 b% X1 ~7 d8 j  uint32_t flags;5 Y) _9 I3 |5 ~9 g
  uint32_t count;
1 T6 D5 q/ f$ W# L  ~2 h; h  uint32_t index;; {7 T) O' L  t* v3 l
  uint32_t i, n;
- i  n; k8 F& w2 ?2 J  //(void)   argument;$ a! _6 [* ~3 c( I

2 s% U0 d8 P+ w) ?1 I  //timeout = osWaitForever;
& O' k" v! {. |: f  G' H, _7 g8 j* J; a2 B7 T/ s; r
  //for (;;) {
* c, j/ Z; m* I    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);4 R& o' Z) c$ \2 H- O3 s# {
                if((SWO_EventFlags & 0x01)==0)return 0;
0 B! j6 a- Q1 F$ q9 `         7 D  V6 [3 M4 M# u
                flags = SWO_EventFlags;7 U5 u0 w4 L" v! W' c5 J. \4 |) S
                SWO_EventFlags = 0U;
; O/ b4 {/ G& ]" [/ D! X7 }9 x1 J    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {& a! K: O' J9 y0 N$ n
      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
4 D9 J3 P" Z  g  I0 C! ~6 y                        ;7 r# p* L5 N/ \
    } else {
  H5 z# X$ h- `9 w6 M9 V* S% k      //timeout = osWaitForever;
' u- I' ?5 f) u; A' T      flags   = osFlagsErrorTimeout;
9 b6 @: {% \$ q, W1 ]& N( \* z  \    }' [. @0 u0 t7 a) T
    if (TransferBusy == 0U) {% C8 ~& p1 a: a0 s, t5 J4 }' l
      count = GetTraceCount();
0 O$ V+ ?9 W! i      if (count != 0U) {
$ Y! C1 }" ^5 S# ?/ ]  p        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
0 _: \7 ^! J9 v        n = SWO_BUFFER_SIZE - index;
8 I( q# w8 _# y' n4 S        if (count > n) {
. G& \+ Z) M% t" n7 m0 K1 u$ V          count = n;5 s) X% {4 `2 S0 `/ R2 [) E
                                       
1 U! N; s7 T( b$ ^0 C" q. [/ C2 l        }  ^% u3 i# {  l0 \  {0 D; \4 i$ y
                                if(count>USB_BLOCK_SIZE)
  ]0 I; Z" s, t" \9 D2 _+ l) [/ ?0 x                                        count=USB_BLOCK_SIZE;0 A0 R, h* O0 L4 Y/ X
        if (flags != osFlagsErrorTimeout) {/ V  X# P3 B. n
          i = index & (USB_BLOCK_SIZE - 1U);
8 j) g: b+ ]4 a& P          if (i == 0U) {
6 k6 ]4 g+ k9 v. V0 `) s            count &= ~(USB_BLOCK_SIZE - 1U);7 z1 A2 E. f; J  r1 w' ?
          } else {
" y# v6 o6 W8 i5 @% B) A2 U/ Q( x            n = USB_BLOCK_SIZE - i;( l7 b  G5 l( b' {
            if (count >= n) {1 B6 U$ l( _2 ?9 w6 L
              count = n;
6 x& z2 U( o1 U4 H- @- [            } else {$ Z' B" p  O) s
              count = 0U;
# p4 {  a% ]& i            }
. V! A6 r8 e2 X$ c! P: R  K( t3 O: J          }* k  I: @1 f% x9 V6 @
        }
. ~9 a& g# `! g: s5 e        if (count != 0U) {7 `/ ~, s! i8 ~" d6 U# m& ^. g! Z
          TransferSize = count;; ?; n1 E# n+ [7 P0 o
          TransferBusy = 1U;" I3 z$ M2 W1 P+ {# N6 ?9 {
          SWO_QueueTransfer(&TraceBuf[index], count);
: `! E. f! D8 y. K  H        }4 e/ Z# ?' i. A$ I9 o8 I
      }
  j! ^! e( s" |) D1 `    }
: W- V- P, K/ `4 S4 `7 u  //}4 O7 q$ ^1 p8 T* {+ [0 [
                return 0;& R: ^* T* o9 M/ m  p' V6 s
}
" x4 I3 Q7 l; E8 b' {1 O利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.
4 t4 D6 F* d' ?' b#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).3 i3 v/ W2 r8 T3 z: u/ x) D& T
static volatile uint32_t SWO_EventFlags=0;6 i2 T/ I, x: T0 s& D" ?+ C! }
static volatile uint32_t timeout=osWaitForever;
) E% l- T! P: e. c, n- q) n# kstatic volatile uint32_t timeWait;
, Z  n7 L/ S: L( T函数改为这样
2 u! w( X- K5 Q  \% u: F/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {: i6 O/ B  z+ t; R
  //uint32_t timeout;9 Y; \( I; H" v; X6 t, S; r
  uint32_t flags;% G* N# Z* d/ d. {! F; v$ O) n& {# u
  uint32_t count;
" Z7 z: m+ d+ R- r/ m2 Y* p7 l4 m  uint32_t index;3 e) o$ v) ^7 U3 X, r+ u
  uint32_t i, n;% K1 x5 B& o! ?8 k
  //(void)   argument;
) R3 R4 R* d4 i. A+ ^; i8 s" S5 z' h8 K: P' u. E$ l* \
  //timeout = osWaitForever;
5 `; c" h) q5 Z  M
( L) \2 @" I0 G6 F4 o6 ^  //for (;;) {/ R3 H: G* H: ]2 W+ f
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);: T' Z+ f1 C- o! a
                if((SWO_EventFlags & 0x01)==0)) h* t. [. E" A8 P
                {9 b* z6 ?, m3 e3 P# O3 `
                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
$ @; T( E! e# A  J, q+ P5 T                        return 0;
8 N" e+ T( T% E+ y( _                        
9 J& P! g% d( E0 g- Y8 C& ]: N8 B                }" B! I; e- ?% }' Y) B5 [3 c6 i$ V
         
) P2 y, q, `2 T) q                flags = SWO_EventFlags;( A' V. ^; K0 F0 K+ c
                SWO_EventFlags = 0U;
6 }8 h. ^: U* ?& e+ |* j' B5 f    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
# g: H9 {- s% |, k$ M( V: F      timeout = SWO_STREAM_TIMEOUT;
3 n2 |; N! G8 f) l- F/ v' O6 v      timeWait=DWT->CYCCNT;
" l* }5 e; `# r6 B9 W  k    } else {
5 W& S$ e) J, h: u" s9 h      timeout = osWaitForever;
# j; e( s& h! \' J- C      flags   = osFlagsErrorTimeout;
: X7 W( P  P9 P0 p    }
8 l) ?: e) j- ^3 K9 `    if (TransferBusy == 0U) {$ `- P8 c, m( |
      count = GetTraceCount();+ ^; s8 t! K$ j8 l5 V8 Y
      if (count != 0U) {' i, J# }% e# [
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
$ d1 c) J7 `, h/ `& S! b  i        n = SWO_BUFFER_SIZE - index;6 p/ \' a& F1 U' |
        if (count > n) {* a. e* {6 A- ?) Q+ G6 m* n
          count = n;2 f& e/ p7 h7 [
                                        & X/ M) A6 x8 }  L; j
        }3 c$ t$ b) ^. r% s0 P/ [
                                if(count>USB_BLOCK_SIZE)
3 C. a3 W& A3 ]! r: |                                        count=USB_BLOCK_SIZE;
$ U$ K% z$ z5 _) i        if (flags != osFlagsErrorTimeout) {
5 O5 _3 U7 ~/ k          i = index & (USB_BLOCK_SIZE - 1U);
1 A. D! N! h" r- b: X          if (i == 0U) {
3 [  Z- ]7 b- Y2 T. A9 R            count &= ~(USB_BLOCK_SIZE - 1U);
/ F2 a! s5 f8 F          } else {
$ C* C4 }4 Y; [0 `  \* D            n = USB_BLOCK_SIZE - i;
$ x! o5 @1 a! n8 `. D9 @+ N            if (count >= n) {
& {/ w' @% o8 I. O) b+ k              count = n;$ t& Z( y; \4 _- l4 _2 \" q
            } else {
; J2 [; f4 e+ B              count = 0U;
& S4 K$ Y, s& M- w/ `  {            }3 j. k1 m: p/ {5 W3 l$ |0 N2 [. {; L
          }
* T+ h; Q+ ^) w) g' e& \# G' f        }
2 O1 `4 _8 P5 G4 K% v$ z% ~        if (count != 0U) {" {5 w/ e7 F6 R9 n
          TransferSize = count;
9 R4 M6 o6 S& J! s9 a, Z8 B          TransferBusy = 1U;4 o% s9 z) s, l3 x4 M  P" |+ c
          SWO_QueueTransfer(&TraceBuf[index], count);
1 H4 D' h6 {6 _3 F. p5 I( S        }
) d5 I0 w, f$ m! @5 O      }5 e# ]& r4 B3 L3 M6 ]% K
    }( z% }0 A/ q- d# x- H7 _: P* w
  //}
4 m. ^4 n7 B$ f                return 0;
+ K$ {) {- m+ j* q, x% l4 l}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了9 M6 X: c+ J* g! r! H/ R
$ _& w' |) }- Z' m/ E% |6 H
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,少了这个等待时间,能增加端点的传输速率  Q# o5 i( y* n" `3 o7 j

9 C  M% ^% j( `4 Y; r2 I8 F3 H4 i& X: M: C7 Q, K* I! i  [2 Z( p$ V
int main(void)) d$ P, I; x& X9 y) u
{
+ l/ \; U9 ~6 o, A8 i9 d  DWT_Init();
: U, l0 a$ G$ `' I6 [- g        DAP_Setup();
. F" K# u2 }: T$ o  USB_Interrupts_Config();
) e, G3 `. {- z7 d; U) G, v! w. R  Set_USBClock();
' q' A) J  U7 p/ y  USB_Init();7 G4 O& w  K. ~( O: J# Y  x
        //TIM3_Init(35999,0);! j; y0 e3 T) C6 K+ D
        //TIM_Cmd(TIM3,ENABLE);5 j6 o2 y1 g1 k6 Y
        / W1 b  ?- C$ f3 {) O
        # R2 h5 `3 `$ s; `$ L$ Z: e
  while (1)' C1 G" ]' d, g# J
  {7 A0 b, P( O  N! @  X. y
                DAP_Thread();
" F1 ?; f, g1 n  ]                #if (SWO_STREAM != 0)
( W7 h8 p$ T3 e; D5 h/ c$ \                SWO_Thread();
" M) Q! L) B2 V2 g, F6 m                #endif- s& v; i7 H+ d# O, l: K# v
  }" ]- O3 j5 y8 h& ~0 k$ f
}
; M, ^: @- e6 b- E* ^# {% P0 A" H- n5 o* x; Q" X
对于DAP_config.h的IO配置我是这样弄的- c3 q0 @1 f, K2 Y! u
///@}" L; A, b& E" [/ J* f, Q/ p" g
// Debug Port I/O Pins
( _6 p1 u9 J' e/ `
( e/ Q/ K& Y+ b4 v/ N// SWCLK/TCK Pin                GPIOA[6]' |# v8 r' q4 Q6 D9 @/ |0 {
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
1 k4 K, l4 \/ R& Q2 K+ X5 [#define SWCLK_TCK_IN                               *( uint32_t*)0x422101180 f4 I3 @1 Q- _. g6 R" D

: h" G  T/ `  e. s2 X// SWDIO/TMS Pin                GPIOA[7]
2 Y0 M" q( \: Z: N#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C
: k6 Y* h& E, r6 b' ~. u& j#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C' `% |: T3 i! A/ A0 I9 |

2 {5 B2 Q6 P; V. P5 D  {// SWDIO Output Enable Pin      GPIOA[7]
& O% }# d# s" D  h7 J) ?3 k#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \3 [, K3 p5 G1 E  c" U; w
                                                                                                                                *(uint32_t*)0x42210070 = 1; \. n$ o# D/ {5 x# Z/ N8 ^6 A
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
* G$ R. T1 `, n( ~( E2 n4 T                                                                                                                                *(uint32_t*)0x42210078 = 0; \6 `  J9 y6 n+ T3 ~0 U
                                                                                                                                *(uint32_t*)0x4221007C = 0;}
( p+ }0 T2 A8 o: y5 a+ H0 U+ R" L7 {1 D: h
#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
9 y2 z3 F) Q4 f! T! y7 X% p                                                                                                                                *(uint32_t*)0x42210070 = 0; \' _& t' d3 y. v$ T, i- K
                                                                                                                                *(uint32_t*)0x42210074 = 0; \
: |8 y3 d; _/ L1 S% n                                                                                                                                *(uint32_t*)0x42210078 = 0; \" s- `" f- r7 A7 E
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
& R. u8 K! }# l$ I+ _4 s
6 G1 K# ]7 W5 v2 @2 D// TDI Pin                      GPIOA[8]2 Y( K0 d, p! C4 S
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0
/ \* p3 E2 w4 p" f# _#define TDI_IN                                     *(volatile uint32_t*)0x42210120
' M& |! a5 H7 D0 p1 G: M4 r* |, k' n& z% e
// TDO Pin                      GPIOA[10]
$ G, V% g. z7 Y* e#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8& z) B& f( B2 {4 U
#define TDO_IN                                     *(volatile uint32_t*)0x42210128( _1 J* b; l* X8 c2 n! y1 n
( V( E( L  I1 f% J( a, I) M
// nTRST Pin                    GPIOB[3]
' t/ J4 b5 y# Y3 w5 V#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C* w' v$ j0 n8 H1 F! f
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C" L: J% B. X! ?2 r$ Y$ D
  D* m" W7 h1 a. K, `/ @
// nRESET Pin                   GPIOB[4]
$ |5 C& M: N8 V) C+ J#define nRESET_OUT                                 *(volatile uint32_t*)0x422181908 }* {1 n- l$ Z/ ^+ N' ^
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
  W' k8 u  H7 T1 h. X  V3 m  D; P1 J2 j* K
// nRESET Output Enable Pin     GPIOB[4]
+ D. ?0 W, k( ?) w#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \! h! E" l5 @+ ]; w
                                                                                                                                *(uint32_t*)0x42218040 = 1; \+ W' @: s! G2 o
                                                                                                                                *(uint32_t*)0x42218044 = 1; \$ X" z# X$ f' E8 |+ j, y
                                                                                                                                *(uint32_t*)0x42218048 = 0; \
7 c- n( C- Z) U                                                                                                                                *(uint32_t*)0x4221804C = 0; } - U$ [0 I) O* J5 T& H. S  F
3 j0 g& q& T. ?- m9 c  b" @
#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \4 K) O; i  J+ K1 l6 O
                                                                                                                                *(uint32_t*)0x42218040 = 0; \  f( O- l- j- ]$ r5 x7 q4 Y1 E
                                                                                                                                *(uint32_t*)0x42218044 = 0; \
, q) M/ R2 W/ W3 F0 P                                                                                                                                *(uint32_t*)0x42218048 = 0;\
) R/ F$ D( E( h/ p, s                                                                                                                                *(uint32_t*)0x4221804C = 1; }
/ O+ k* m! `; T" H* v# k2 N# T* d# J# {/ b

) M( Z2 ~- i0 e5 [5 P/ t$ |1 r// Debug Unit LEDs
+ @$ h/ n# |3 t# h' L
1 l) T- K4 T$ @* \! U6 J" H7 u// Connected LED                GPIOC[13]$ P& _& y% B( Z7 R4 G5 N5 Z( Y; u9 ^
#define LED_OUT                                                      *(volatile uint32_t*)0x422201B44 D0 h$ ?, z* h
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
8 m. E9 T# T6 C! J% i
9 f6 [0 ^4 ~3 T7 B$ D& w0 J#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
5 x( D; o) L: T  Q. J                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
9 t8 S" Z2 T3 u% `' ]3 j                                                                                                                                *(uint32_t*)0x422200D4 = 0; \, [0 D) X* j/ ?5 I0 c; Z$ T! Y$ Q
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \
) X7 m. ?5 Z  G; \$ j% k' N                                                                                                                                *(uint32_t*)0x422200DC = 1; }
, j0 A% V. m& p4 J3 ?$ x// Target Running LED           Not available
# a. A$ g7 H& S" W  _! H" G
; y/ ^3 ?! @5 Q" \5 C0 S, d// SWCLK/TCK I/O pin -------------------------------------
1 A" N5 R2 v: y/ {2 s4 G9 F7 K/ L* D6 ^) y6 R) [' u
/** SWCLK/TCK I/O pin: Get Input.
. u8 s( ?! y4 J4 I" g\return Current status of the SWCLK/TCK DAP hardware I/O pin.
8 \* @" I( K2 F3 r8 H*/) I3 N" K! p- D2 p
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {7 E8 U* q" V) e4 N- R
  return (SWCLK_TCK_IN);3 ^+ e! \, c; e0 `7 e  F$ n
}; s6 J: P% M* P4 t# `2 H( ]
' J* `/ x& ?" }& l
/** SWCLK/TCK I/O pin: Set Output to High., _$ u9 c, d( Y' G3 o
Set the SWCLK/TCK DAP hardware I/O pin to high level.
# w1 M0 M$ }/ p1 R# B2 m*/
5 i' m( v8 f) O4 s! C9 c__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {! a, @9 }! H/ g0 t
  SWCLK_TCK_OUT = 1;
# [! P! o5 o' K* V}
4 _+ g2 @5 Q5 t
3 c% v  q% c: J, g6 j/** SWCLK/TCK I/O pin: Set Output to Low.
. [+ o0 a  H& O- XSet the SWCLK/TCK DAP hardware I/O pin to low level.
$ ~2 X. M. g- y* W" r0 Z*/7 T% l" G# \8 p. F
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
& A5 n! L) q$ D7 e" n  SWCLK_TCK_OUT = 0;* _) C8 I/ Z0 ], x7 ?. c
}* R9 c, Z+ {5 x  {

' X- ?8 {4 Q& Q; b
% b3 s" v  D1 |" ^4 S// SWDIO/TMS Pin I/O --------------------------------------
9 q5 Y! m( l1 k: N* I* P7 h! J. H5 S, k/ x6 v& O, l) ~2 O7 v8 g9 T
/** SWDIO/TMS I/O pin: Get Input.
7 X: V+ E! ]0 N' F  `: E# r+ l" K& h\return Current status of the SWDIO/TMS DAP hardware I/O pin.
9 h$ S' b; n2 ~, t4 x*/, }0 W! i8 V9 @$ h+ M5 L
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {: j4 P2 @: W$ }
  return (SWDIO_TMS_IN);% d; J' i2 C6 C3 p
}
& y9 G6 z, P7 W9 D. j8 n* |0 I% B" U! B2 _3 c( ~
/** SWDIO/TMS I/O pin: Set Output to High.$ A4 |0 ?9 m' |  l2 [
Set the SWDIO/TMS DAP hardware I/O pin to high level.
6 ]  Z6 ~: p% x  W; f; g2 o  Z*/; y& ]& a& E( p2 s
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {  w: Z' |- U/ @+ ~# e5 a8 l- q; w
  SWDIO_TMS_OUT = 1;; p6 w8 ]1 b7 C2 w
}
. k: m& k. Y! O7 F% c- U4 @4 l; |' l- }+ H% E4 v7 E, \
/** SWDIO/TMS I/O pin: Set Output to Low.
' |5 P/ U9 y9 y+ q( y( y) A% @Set the SWDIO/TMS DAP hardware I/O pin to low level.
- |& C$ n5 _2 r*/( J9 G* }7 s7 j: h; m6 O
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {
2 y5 H, x: d+ z& P7 p& R) w3 V  SWDIO_TMS_OUT = 0;: F% ]  G2 g+ I1 l# W
}1 i6 H. _6 ?* g7 A
- J0 ~/ x& i) P7 ^; k: g  W+ ~
/** SWDIO I/O pin: Get Input (used in SWD mode only).3 O; s* |; b5 S
\return Current status of the SWDIO DAP hardware I/O pin.
1 c. I% l" M  A  z, X( D* `1 D0 l*/
- K0 |0 T- F9 h* q- F__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
) d5 h- O( T& W# ~9 Z9 f  return (SWDIO_TMS_IN);
, \: a  u! e3 t5 S7 E4 r}/ Z% h7 r: F) E+ ~
+ Z  R3 w  ]3 `
/** SWDIO I/O pin: Set Output (used in SWD mode only).5 B$ u! E- Q" E% |. }
\param bit Output value for the SWDIO DAP hardware I/O pin., J* n% [) M& C5 S8 s
*/% d; ]0 @& }/ s! @
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {$ R% c1 I4 ^  c* E0 A$ g* ]- ~
  SWDIO_TMS_OUT = bit;- n4 N3 H/ D1 p) _
}# t& q6 p: [! Q7 ?  C7 ]

: K6 V$ y7 O: `- S& w2 D/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).0 f, x0 A0 j8 ~+ f7 v/ y, y2 D& f
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
5 ], V) i$ }' k# J! bcalled prior \ref PIN_SWDIO_OUT function calls.
  ~  D5 e# V0 ?9 B+ E1 W*/3 o0 L1 ]1 O" L; O8 T4 a8 h% s
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {' D  D2 W+ `; d$ {
  SWDIO_Output();
  b2 [% z7 `! P4 K3 v0 s}
# y2 A- a0 |+ c$ L$ X
' @. T/ U3 j& u/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).% X# Q6 E* f9 Q# ^
Configure the SWDIO DAP hardware I/O pin to input mode. This function is6 R) z1 Q" Y) a/ ^. U
called prior \ref PIN_SWDIO_IN function calls.
& o# |3 Y  }& q: h*/
2 s- \0 N6 D! j1 T__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {/ r& O+ ]# a( J! b
  SWDIO_Input();
7 h3 A5 j4 l# _$ r- I}5 X+ {9 B' [, G7 K1 N* U" g

$ G5 P6 ]; b& ]; M5 s楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
- t  X% \3 K- L) L8 O+ r7 o. z即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
2 ^4 h9 c/ @2 B3 Y  Z0 w+ a; a
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版