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

【源代码】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,希望做一个,让复位时给一个低电平复位信号。1 I% J/ S, N! g; a9 A3 R
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
+ E! ^8 D& n- O除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
$ v& u9 b, J6 P
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。( m. H/ ~: [+ X

, ?* Z, x6 ]; |/ H$ k软件复位是另外一种情况,需要向目标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
) L* X, N% B2 T$ N* U! y可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
) Y0 t- z/ i: `# \
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。% j& q3 K! r  n0 z
你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。, k7 c+ M3 J- `% i

/ W' Y' p& z5 r你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
! p  q2 z( z0 Z9 d/ \4 P或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。
; A: H% A. X, r% A( L4 @9 t3 L
- g8 v! H6 ~; q7 A& a3 Q2 F! W% X2 g$ e: N5 h8 h# l* L$ O; A. c
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?
3 g/ Z- D2 z8 b' c
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap * {+ i0 W- j0 F6 Y
起点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系统,轮询执行
+ e+ l) ?# K7 b! D# _# V/**& [+ n; d% f# G; v
  ******************************************************************************
8 U0 G& P6 r/ y0 c' U  * @file    usb_endp.c
( u' @; u& r7 b! a3 r  * @author  MCD Application Team' N) ^3 b+ X: J  }9 l# E/ I
  * @version V4.1.0
( V5 b+ u. T  Y+ [& Y/ F' N' @, Y  * @date    26-May-2017! h6 y+ N( u; ]
  * @brief   Endpoint routines/ a7 a% V( O6 m" h8 i; s
  ******************************************************************************
4 i" k' Q( c% j7 W  * @attention6 `1 W5 B+ j, p/ p( ^; y
  ** \7 j) l' c" z
  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>& M+ o1 [* d7 m. p' Z- E
  *
! y% D- Q- J6 _+ }( J  * Redistribution and use in source and binary forms, with or without modification,: I' Y6 {, B; u# `
  * are permitted provided that the following conditions are met:
3 i8 i2 t" ?/ W6 }* b' ~1 `5 H, l  *   1. Redistributions of source code must retain the above copyright notice,. U: w4 O! [$ @& a" Y
  *      this list of conditions and the following disclaimer.
( C, t! G. {% t! Z; o  S, H  *   2. Redistributions in binary form must reproduce the above copyright notice,
, W" j$ v, `# P" [) m. \7 _  P  *      this list of conditions and the following disclaimer in the documentation7 O3 h# Y2 Z. N
  *      and/or other materials provided with the distribution.
+ \4 f* O- {  G. l5 g2 q6 S  *   3. Neither the name of STMicroelectronics nor the names of its contributors
: ~# K6 T( t8 a! d  *      may be used to endorse or promote products derived from this software
- r; _7 q7 x8 [( ~/ }  *      without specific prior written permission.. i& p# u+ i& i4 ^: B2 j: \
  *$ {& h5 {4 p0 `1 ^" q
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"& T& m. I% N2 s. U* l6 ]! h6 h5 @
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4 X2 f+ s( s0 H3 a8 D. z3 W  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
$ u# Z% E6 P1 ~, ?  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE' q" X! o& b) S
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8 E! U5 O, `$ |! |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR1 m: l$ D% o- D3 o( @% j
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# ^0 H3 \6 {/ ?" t5 e* A  b+ l  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,( A0 ?& F8 e5 x  o1 p0 f0 v6 s9 d# n
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2 m. O" s- M% Z" x; ~, y/ c  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7 G& l: K6 a( Y$ r8 ~# O0 V2 w  *
/ c. C+ R7 s2 u( k# b  ******************************************************************************% }4 {( V  ^  y1 B2 r8 W% V
  */- G7 ^7 p' R7 {* T7 e8 ?

/ C. h8 l' {' z
; O, {. w# k( J" L" k* l: E/* Includes ------------------------------------------------------------------*// M) @( n7 }* [
#include "hw_config.h"3 m; x9 V) [2 H  x
#include "usb_lib.h"
, g# n' ~' t0 e8 t% T4 M7 a#include "usb_istr.h"' X. a" `# o! Y. b" M' \
#include "stepper.h"0 r  b' j' B% |8 T
#include "string.h"
: C9 y8 ^9 d" W2 \. n' q7 w- F8 r, T' h
#include "DAP_config.h"& b3 x" e( f% {' d2 m5 a
#include "DAP.h"
$ ~' f  s0 [' m8 _$ w9 i9 b  E5 c/ L+ m1 w
: Q" r3 p; d7 O
/* Private typedef -----------------------------------------------------------*/
1 l' T( B& Y3 Z$ r/* Private define ------------------------------------------------------------*/) C! \$ S. T; t% m
/* Private macro -------------------------------------------------------------*/
- P2 I' q' h' _1 w, o+ S2 _" e: |* e/* Private variables ---------------------------------------------------------*/
6 P7 b2 i/ f+ i% i3 Dstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In% b/ z- u- g: R2 c: W0 x
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out
) O& X0 q0 h- V2 qstatic volatile uint16_t USB_RequestCountI;     // Request  Count In
, _; ~( z4 _$ {3 O: ?& \static volatile uint16_t USB_RequestCountO;     // Request  Count Out
( m7 w3 t: ]. \static volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag' W( Y5 A, O& ]
( B& `% N- |5 g* A0 [
static volatile uint16_t USB_ResponseIndexI;    // Response Index In
, r: R2 n+ T' }) ]9 \static volatile uint16_t USB_ResponseIndexO;    // Response Index Out
) \: F9 Q/ \, [; p; Lstatic volatile uint16_t USB_ResponseCountI;    // Response Count In0 ?1 s4 P  A2 W( c: }1 z  T
static volatile uint16_t USB_ResponseCountO;    // Response Count Out
- v, c% I! O0 x9 a) f- l% p; Bstatic volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
4 W7 C5 p- R. _" w5 c6 S5 ~7 P1 H1 Gstatic volatile uint32_t USB_EventFlags;
$ M: v- `# m* m
9 ]' c# [7 u7 E6 B! r% _static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer
7 P( N. H% E- }0 S' estatic uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer
6 \4 Y, F5 M# R/ u% estatic uint16_t USB_RespSize[DAP_PACKET_COUNT];
" t  d- Q: U, K, L+ Z9 u6 O' }7 r# m6 G4 x+ }
/* Private function prototypes -----------------------------------------------*/
6 m4 s# d" j6 S3 ~( @% u/* Private functions ---------------------------------------------------------*/
2 B- X$ Q* D8 U6 Q% U/*******************************************************************************
1 ?; S7 w3 g2 V6 z" |* Function Name  : EP1_OUT_Callback.
9 K$ i9 h9 R* ?( C3 [4 P2 f: u* Description    : EP1 OUT Callback Routine.
0 z6 n  E/ f2 F* Input          : None.
/ |9 T2 B  d1 F6 _* Output         : None.9 l, U9 a1 u" z8 D  K
* Return         : None.% w. x2 h: M3 q, h) o
*******************************************************************************/
) K8 T! b, z+ Z' `/ Z  c& W' M/ G# Dvoid EP1_OUT_Callback(void)
9 i1 J) f! l- E: H6 m8 K) y- L{
( e& B" H9 @3 O+ r" B8 @: F: S* `        uint16_t n;( F3 ^- n6 \& F9 ]6 {# Z. L

( O% e3 p  V& \# F* v2 N        n = GetEPRxCount(ENDP1);( U: ~% r0 C5 s+ q3 k/ g. d; s. g. j$ e
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
% I) o5 w( n# d1 v; z% X) U        if(n !=0){
3 z! {2 U% a: ]                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
, y$ x( o5 N8 {( Q3 ^1 W' I+ l                        DAP_TransferAbort = 1U;+ e' ]) A. h% t, t% _0 C
                } else {
' \" {1 n9 p4 E: d8 s: N                        USB_RequestIndexI++;  J2 w: A$ S1 g: r; H
      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
& ?$ ?+ i3 @/ n2 s  q) O                                USB_RequestIndexI = 0U;
' T+ p. Y# H3 {/ p; {9 m+ o      }8 Z8 l6 x6 l- v" M
      USB_RequestCountI++;
2 I- a. _) u! V        USB_EventFlags = 0x01;. I% v) p/ N0 h+ M! i/ O
    }
- {0 a5 r! z6 K$ v9 _9 R4 t' c! M        }        
+ Q1 p. s& B3 s  Z) Q        // Start reception of next request packet
, g7 L4 s8 d: U; u& I3 Y% p        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
' P5 V7 _. J; T- G- D                SetEPRxStatus(ENDP1, EP_RX_VALID);
. i* g) V# B% z( O  A! M/ k        } else {* B% _" W, b2 _; J4 y
                USB_RequestIdle = 1U;/ c% n4 Q6 B  e9 K# y* ]5 c3 M
        }                        9 n% X/ Z5 w1 U& H, y6 O/ R4 S  m
}
- Q6 Q; M7 Z" k, p4 D% x+ K) \+ h+ X: p. [/ ^
/*******************************************************************************
9 s% Q& H' _4 {$ L* Function Name  : EP2_OUT_Callback.( s" k' {9 e2 [( W
* Description    : EP2 OUT Callback Routine.
4 m9 J! x* ]2 A* Input          : None.
3 o1 n/ T8 R+ M4 `2 w: d; C  l* Output         : None.
5 Q6 y$ Z8 J& U7 e& [8 o- ^* Return         : None.7 c. V) s9 Q3 \  H& a# l8 }
*******************************************************************************/, O& j9 o1 U( Z1 X5 }
static volatile uint32_t TX_n;
- j, a+ G- G0 t/ G! astatic uint8_t *pbuf;+ j9 G6 ?/ v6 G& r0 }* L
void EP2_IN_Callback(void)
" N  }# _5 o' n7 w: O1 c6 X2 ^{/ ?, @+ p4 D: h8 [
        uint32_t a;
& |5 }% p3 i8 {# z        if(TX_n>0){
9 a. w- _* o, j$ f8 }                pbuf+=64;
6 A" K& y7 d" A' W. t5 C! Z. `                if(TX_n>64){
  o9 j8 D" P0 M1 \. ?0 @9 p5 F                        a=64;1 \( L- }/ \( {% w$ O
                        TX_n-=64;
& e0 a* B: b5 E, H! D                        
9 y% y" I/ b4 b5 y( Z0 s$ B                }else{
+ k3 H9 o2 Y5 q& }3 ~                        a=TX_n;6 y9 e5 g( x5 F
                        TX_n=0;
* w1 X  m6 W2 p( J9 {                }, _4 q, m. s, R2 j. J
               
% h! P. z8 z0 j( N1 B- ^, ~        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);; x6 T+ e  [' b1 Q' c
        SetEPTxCount(ENDP2,a);
# l- K' s1 l7 k7 D: j( `               
' V9 b4 I' t+ Z* `4 N4 A8 _/ e! y7 n        SetEPTxValid(ENDP2);
9 B: A+ |- s; {        }else{
. d/ w0 S; G% n: G4 _0 E) i4 h3 |                #if (SWO_STREAM != 0)1 h, X3 Q0 p& |$ P# g* A# |6 ]
                SWO_TransferComplete();; V8 m$ [' P7 F( ~) a
                #endif
) n! m+ \2 I6 y5 ~8 q- A        }
  A0 e; N: n/ S  W}+ D! B! f6 I9 C. l
1 o  N1 @1 ]% L- R
/*******************************************************************************
8 P: x. m+ l" E* Function Name  : EP1_IN_Callback." h8 @% ^2 ^0 a7 t1 d7 O
* Description    : EP1 IN Callback Routine., x9 f8 {% U5 ~/ f8 O
* Input          : None.
% V4 s0 k+ a7 ]5 d* Output         : None.
3 \% T: F% q. l& F) G* Return         : None.
9 ^9 @* j) h1 b: x& V6 B. ^7 ?$ O# a*******************************************************************************/1 R* b, [$ K* C4 O: ]
void EP1_IN_Callback(void)
: I" K2 v$ I" y. g{% B7 [, B* ~+ J, u, B% Z
    if (USB_ResponseCountI != USB_ResponseCountO) {9 d# D) ^% ?/ C4 R. j5 K/ i
      // Load data from response buffer to be sent back8 |( x* ^% I' h$ |0 ?6 w( f) _$ W; S
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);# R( W, J% }/ [8 m
                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);
8 {( l3 _  C! u  E! s                        SetEPTxValid(ENDP1);                        
4 a: ~5 j. e: \7 T, x! l- Y7 L0 V7 c2 m      USB_ResponseIndexO++;( l& a4 F# E2 n2 R- I
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
/ ~/ y4 ~, s' B: S" w& j        USB_ResponseIndexO = 0U;
8 a& E. F/ Y+ X/ [7 D      }$ ]4 G# a5 d: o! x' e* d6 A+ X
      USB_ResponseCountO++;8 b! H) b3 f! ~- E, T* m% w7 e
    } else {6 A! n7 d9 s- X% B6 f
      USB_ResponseIdle = 1U;
' z+ |7 ^- z$ q& e# ~    }  ; s6 K7 A* g4 K8 e
}
. T! e% Z# L1 N. {8 \0 V- T5 e
: _7 z( V- w5 ]# \// Called during USBD_Initialize to initialize the USB HID class instance.
5 n( m6 M- B( g- [% Y# ]1 Mvoid DAP_FIFO_Init(void)! K$ H! |) D  D
{
( B- a6 y6 L, `7 y& D2 s    // Initialize variables
4 |; k3 P1 @, n# f3 B  x    USB_RequestIndexI  = 0U;+ {+ y, ?  X* X8 x$ p# c# `( @
    USB_RequestIndexO  = 0U;2 l8 ~+ m3 F& V( j
    USB_RequestCountI  = 0U;: Z7 @4 q( r" h, C
    USB_RequestCountO  = 0U;
0 C& i& T( a7 K% A" |4 ?    USB_ResponseIndexI = 0U;
8 v: p1 A: X6 J    USB_ResponseIndexO = 0U;
- |6 v5 g# m- @2 |4 S# e  |# _    USB_ResponseCountI = 0U;
% o5 {1 {" C, m( H$ }$ S) F    USB_ResponseCountO = 0U;$ P: B2 Y! Z8 ^" s3 Y- Z% {6 g
    USB_ResponseIdle   = 1U;6 {' f7 _+ m- b' H
    USB_EventFlags     = 0U;; r8 {4 ?- A# ~) H7 h4 ?
}
9 ?* C/ p8 _! d: l- N2 S0 v! S0 g5 M2 s4 M! J, [/ y: x1 _
uint8_t DAP_Thread (void) {
$ N  M0 a$ I0 j# b  uint32_t flags;
% @' D, A2 D/ A1 L5 z) L* d! }  uint32_t n;+ A; y  Q. ]3 e4 v2 m8 z% Z

& Q% J+ ]2 g, q& S  //for (;;) {
/ c5 n. R/ Y) [  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);5 N8 h: ]7 N" q: Y
                if((USB_EventFlags & 0x81) == 0)
4 V) J. E. v* C3 Y                {: T; w- K$ F' w7 n2 i1 u2 @
                        return 0;
+ Y& m5 s2 c8 z                }3 `( x/ H. A2 J' C8 n
                USB_EventFlags &= (~0X81);* m& b& i! w& \' l4 y4 E
                , V  L! Y8 q2 n3 s/ r7 l
                                        8 U% h/ M: ~, r7 p- u& \
    // Process pending requests
/ ^/ E8 i$ B0 h. D1 ]9 U% |    while (USB_RequestCountI != USB_RequestCountO) {
# ]5 C5 t3 r$ M: E                //if (USB_RequestCountI != USB_RequestCountO) {
% N# h% t& G- y9 _      // Handle Queue Commands/ D# ]' Z4 S' F5 E
      n = USB_RequestIndexO;* B  E1 t* ?; m8 N. a3 _% L' C
      while (USB_Request[n][0] == ID_DAP_QueueCommands) {. t; D- g1 v( b& G8 P! x
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {
, ?- y- ]. D! A' k        USB_Request[n][0] = ID_DAP_ExecuteCommands;
2 ~! [0 h$ q: l4 h4 \* Z; \9 G3 K        n++;
6 K5 P4 t- B5 R        if (n == DAP_PACKET_COUNT) {
& g- d$ z+ a3 X          n = 0U;' ]1 u( G# i5 W7 ]1 R
        }
  L) K" r4 q, I6 A# h, w8 E        if (n == USB_RequestIndexI) {
" j/ L8 [# F4 n8 {7 E          flags = USB_EventFlags;
' E4 U  z' Q: N; d9 `% G          if (flags & 0x80U) {  g! x- {3 F* R! h( N( V! }
            break;
1 H/ {$ Q; T0 b4 F% M6 S          }
# `) F: x. S5 |3 _, ?        }9 t. s6 d; k: v1 ]: |
      }
  P3 R& B3 n) U: M- Z' X, s3 w8 J* h( f3 J' Y1 R/ B5 y6 {, ]
      // Execute DAP Command (process request and prepare response)! d$ J6 K. z: O3 ~4 i/ G
      USB_RespSize[USB_ResponseIndexI] =" v: M1 B0 j  U1 K/ e: S
        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
3 s" s/ T3 ]" ~( n% A* i6 n& i, ^& b+ u- r; `
      // Update Request Index and Count
( n0 V& M  v( c, ]      USB_RequestIndexO++;* ?: s. t/ H+ \$ Y/ j6 j
      if (USB_RequestIndexO == DAP_PACKET_COUNT) {0 O" i2 D, ^) G0 }. P
        USB_RequestIndexO = 0U;! J4 d/ y* l( r% S
      }& X8 a4 O- |; B3 W/ t% P
      USB_RequestCountO++;
5 M5 y+ K: ~6 l& D/ v
7 T9 N: M% g8 c$ R& A" X) Z      if (USB_RequestIdle) {) Z' w0 h# J. V- F
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {' Q1 u9 {& Z8 g. _2 A$ @
          USB_RequestIdle = 0U;
/ }& d7 G3 W8 j7 S9 l. M* G+ P          SetEPRxStatus(ENDP1, EP_RX_VALID);
9 V* J0 L8 i$ r2 N# }) ^        }
" Z, L( v! L& q# `      }
' |6 ]$ Q0 O& m% A5 Y9 P
/ Y' {6 d5 n' a" k, N* \      // Update Response Index and Count0 A! B+ h1 P! `! Y3 z
      USB_ResponseIndexI++;: K0 t8 w/ ?$ `4 p% x, i" x
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
; R: R) O* i3 Z5 b/ E7 X: N        USB_ResponseIndexI = 0U;
! `2 S8 @( z# L      }% N3 c1 \1 s. J. o1 Y
      USB_ResponseCountI++;
5 [1 ?' @( Y8 d$ g- M3 O3 Q0 E7 E" y9 g1 l+ W
      if (USB_ResponseIdle) {( x- c0 K) W2 [% J
        if (USB_ResponseCountI != USB_ResponseCountO) {8 e# }( `$ P7 f2 t
          // Load data from response buffer to be sent back
3 Y( c4 l6 c; n, B( N! n- F          n = USB_ResponseIndexO++;
1 o. Z2 A  Y! G2 y5 B$ k! G3 ~          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
1 I$ v- J* Q" Y2 |! ~/ A            USB_ResponseIndexO = 0U;
' z. W/ s' D( }3 f          }" [" q4 P: U: d! k
          USB_ResponseCountO++;7 B$ D% U5 {+ u* H" S
          USB_ResponseIdle = 0U;
+ F; p2 U! H/ o3 i) u) O; u; w          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);9 J7 l6 n/ y7 [5 y* x( o" k" F1 E6 r
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);) u; M- V4 \* }+ o, @
                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
0 t/ g: q* C1 T                                        SetEPTxValid(ENDP1);4 R3 S6 v0 w: Z4 Q8 G& i
        }
$ U6 m' G, u9 {$ z7 B- ]      }4 N% A/ d2 d7 L+ z% `9 C% o- q( c5 U
    }
9 ~$ g# n6 [% ]& S7 N1 b        return 0;
; j0 ]; I; r- v3 ~}: p% C3 Q! W( e

2 A  s/ n" d( _, g// SWO Data Queue Transfer9 b4 n  _' R3 I1 p: O
//   buf:    pointer to buffer with data
  b( ^) u( q# c/ z5 B( N//   num:    number of bytes to transfer
$ ?+ D0 T4 e( ~# R! X( E* vvoid SWO_QueueTransfer (uint8_t *buf, uint32_t num) {1 i; u: u. x8 t& U8 p
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);/ Z/ v# u0 j6 K' Q0 s8 T9 T  v
        uint32_t a;
7 y  ], k% ~: e& r2 j        
/ N/ }, Y* _8 N+ R0 u8 J7 |6 x3 @$ W9 I        if(num>64)3 c( |1 W' k% ~
        {
; z6 ?- r! c  _& g8 f. `9 n2 c                a=64;
% d1 }8 N, n2 U                TX_n=num-64;
( C% ]: j; E5 j, Y; j  k                pbuf=buf;" Z8 K! M  w" n) |* N4 O2 A
) a' D% m* C9 F  t( D3 j
        }else {- V8 p! a  n4 c0 }. I  S- `
                a=num;
& x3 n* Z+ Q0 k; r0 {* }                TX_n=0;3 ?/ D7 Y( h+ t9 g& H' o* i/ r' Y7 B
        }
  O. G- @/ l- I$ S# B7 |        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);4 B3 d- ~# _1 Z+ \, |: G
        SetEPTxCount(ENDP2,a);
7 K; g7 s: Z0 i; i        SetEPTxValid(ENDP2);1 w! K' Y- f/ a2 Z
}
; H+ F) u$ N- F+ |$ m8 ?- s( B# P& w* i8 r$ p0 }2 @" j
// SWO Data Abort Transfer
5 y: e$ `- H8 Jvoid SWO_AbortTransfer (void) {' E9 X4 y: K' e/ R
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
6 z2 K& {2 v0 `% Z3 D; f        //SetEPTxStatus(ENDP2, EP_TX_NAK);0 a+ L5 l+ x4 T- S6 |+ F
        SetEPTxStatus(ENDP2, EP_TX_DIS);
( T$ `& N) \! L* G% J. o        SetEPTxCount(ENDP2,0);
/ n* z$ G3 b: Q. ^4 o) b1 _8 f/ q( H        //TX_n=0;: q, k) v3 s$ r% r2 I1 a/ y, Z1 J4 T
}
8 z4 n) T) C* [- A7 R, {$ R/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/- Z4 t( {) C% i' E3 M

$ r! Y; i4 h" ]& ~' _3 d移植大概是这样的,利用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时感觉速度还是可以的,这能体现批量端点的好处. T2 P! v6 G8 ~7 L' b5 {; N
DWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了$ r5 P; F) K5 X  p9 [
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
% x9 E! |! D6 N  return (DWT->CYCCNT);
# }: v2 b7 H: |}
5 @* J" I( Y* z# A9 h; O! M* m; v4 D$ u9 B# v: h
void DWT_Init(void)
$ N( d9 j& [" L6 b$ A{2 P% d5 v5 |8 {# x( o& Y
    /* 使能DWT外设 */9 O, ]4 V) Z1 D9 A. _
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;                . }' e; _, O' U. I; k
( ?; ?( g( K( Z5 o  D! [$ R
    /* DWT CYCCNT寄存器计数清0 */% E" j1 K5 L, V
    DWT->CYCCNT = (uint32_t)0u;& H% [3 h& P' f/ y! m: ?; x
" w2 \5 W( |, w$ M: S: l; Q: d6 o
    /* 使能Cortex-M DWT CYCCNT寄存器 */. }& G5 d6 i2 }1 `
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
# G7 J9 G4 `, [5 t* X}
# j7 M/ q2 ?/ _" Z        
7 S# X4 q4 J& v1 g% ]3 h0 |8 g" t) a" N- r5 a4 A
然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率$ R6 Y3 l% e. U3 @1 @
& l. f3 D! s" w( r' X5 z5 k
然后改为使用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不香么?
8 D- n% O8 j" ]+ ~* f声明这个变量static volatile uint32_t SWO_EventFlags=0;
* }3 `0 x! l0 Z8 B% x在SWO里每一处调用osThreadFlagsSet的地方都改为如:
4 L) m, [' ]/ v2 X0 `//osThreadFlagsSet(SWO_ThreadId, 1U);
% ^/ }7 f% Q8 s- GSWO_EventFlags = 1U;
) ?0 L$ j$ R0 X4 j* v9 K4 }* R$ \$ h' M9 @: ?& d6 F0 A

0 S% {+ D, J, W% ^4 {4 n9 V// SWO Thread
* a7 ]# \: J8 s& L, Z  e+ w" ]/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {
3 r5 [1 o" @! {/ o; V1 B( i  //uint32_t timeout;3 a4 c4 Y+ r  j  u( j: L* A  R
  uint32_t flags;% u% C* V4 y% R9 t* \( ^3 L
  uint32_t count;( j! s6 `% S0 s( O
  uint32_t index;
, K9 O. d9 y* P  `, r  uint32_t i, n;
+ l2 g9 W7 `$ I8 i' u; N1 |  //(void)   argument;
" ?3 M& ?* V' i/ P. G" f# J# y* H0 `6 ^3 B
  //timeout = osWaitForever;: s  X4 K/ O- j( k7 t/ l; u. o

' h) i( T+ x5 J  Z2 ?' j  //for (;;) {4 V# C0 m  w* {( C- J
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);& T6 _5 i* [0 T, R: w/ K2 b
                if((SWO_EventFlags & 0x01)==0)return 0;
( P, |- h% y$ {' H9 s: X3 a( }         
5 C' e' A, I" O& z) }5 v% R                flags = SWO_EventFlags;% P, u+ H. I9 [& V9 U, M9 c
                SWO_EventFlags = 0U;
& ]; R6 ?* U( M0 x    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
5 }; q4 y) C( {" I& N$ x# a' N      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
1 t; P' I* X5 N0 s1 ~; x                        ;
% j) ]- k. m9 H6 z) J    } else {
; B" t4 e! x7 g  t# _" a9 C      //timeout = osWaitForever;
+ v. Y6 [# N) O: a      flags   = osFlagsErrorTimeout;
3 Q7 Z6 O' k' C) k    }  \7 f. c- P) b) H, @* i
    if (TransferBusy == 0U) {
* e8 T/ m( C. |) w      count = GetTraceCount();
% P. ?& v0 {$ T$ M      if (count != 0U) {
4 @" R! d, m+ T( d  e0 J        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
/ G) Y6 x# @" U: W) ]        n = SWO_BUFFER_SIZE - index;
: ^# g# \  ?" a5 C        if (count > n) {$ @; S/ r" G: E& m
          count = n;
5 M+ Y5 |, j3 D6 T  U+ l                                       
- R8 `( H& d3 u0 M        }
( e, V( f0 {3 E' i                                if(count>USB_BLOCK_SIZE)5 L, A9 u4 T; ]! f" h# N2 ~
                                        count=USB_BLOCK_SIZE;
. m: y) P0 c  T) V' G        if (flags != osFlagsErrorTimeout) {
9 R( t, I3 f6 X. ]4 Y# b          i = index & (USB_BLOCK_SIZE - 1U);$ C! F& E3 [, B
          if (i == 0U) {" ~0 Z+ y: l; k- k
            count &= ~(USB_BLOCK_SIZE - 1U);
( e) x; l) ]! k- }! z          } else {
5 g2 ]7 f) r2 V/ \+ g7 v            n = USB_BLOCK_SIZE - i;
1 y, E0 d0 ^+ t  p6 L; F            if (count >= n) {
) }$ v) i; @; D8 M8 ~              count = n;
9 K5 r# K5 c7 p9 E0 |            } else {6 Y' v/ |. ~2 F" F& z
              count = 0U;
! t0 e7 \+ v( T2 c, U$ ?) T            }
5 L1 r. o6 i0 \' \& r% Z; b          }* V, {. b& G0 B3 w$ v
        }! k7 |! [& B8 s; P7 ]% a
        if (count != 0U) {
/ U7 M' ]. g- _: M4 Z          TransferSize = count;
( \# g/ r* s' D5 s  b          TransferBusy = 1U;  N8 }/ g. V, Q; q3 S" {
          SWO_QueueTransfer(&TraceBuf[index], count);
* V! B0 [" C; K% f        }
. a% E$ f$ @7 _0 B! W* i      }
. E: [. I5 P( G4 b  E2 \    }6 s: }2 h5 Z* N
  //}
; E+ U4 ^  V; o                return 0;& S& D) H, W; S: F  H
}
# f7 w8 F# f( Z  y6 N利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.8 ~  j8 F( X( M& z3 J; k) }: r
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).7 q+ l& R# D3 A0 [$ Z+ ^* O5 G6 V
static volatile uint32_t SWO_EventFlags=0;
- C9 P1 W' \* M4 Q: D7 h1 ?% |4 B, l; ]static volatile uint32_t timeout=osWaitForever;
2 Z: O6 C. c) F" wstatic volatile uint32_t timeWait;
! O  w. f* _1 ^! O7 q# |$ c& w函数改为这样' i' o* S) t" W/ H6 j
/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {$ g& u7 y5 q3 @+ w
  //uint32_t timeout;
9 ]3 P2 o7 n. W% ?/ a: ?7 y2 }  uint32_t flags;
5 Q! f3 u% y& ]1 L# D* n! X$ U  uint32_t count;( l* T0 }6 l2 J8 Y1 C- T. h* G# t
  uint32_t index;8 U: I# h' a' G- u9 s8 d0 Y; n
  uint32_t i, n;! ^) V2 [+ t, E1 _# V
  //(void)   argument;
5 s$ X5 q% R! n; }, ]6 [6 @' G* F" ?5 s. m6 V, L# H; s  Z7 O  D
  //timeout = osWaitForever;
" l/ x1 J* O& p; g$ O
# Y2 o6 m- T; D  //for (;;) {% ?! o3 i) J. ~' {. m; X3 [; ?! M
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
- L; w: }( t4 F* U* f                if((SWO_EventFlags & 0x01)==0)
1 ~( {" W" g& }6 D( g# n3 S! U                {
3 V4 W% m* Q% j3 Z                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
0 G- H( G0 g& p                        return 0;
! v6 v" ]7 F8 P7 u+ H& R                        * N8 ]! V- V0 r
                }: {2 T8 U/ ]7 ~' B2 a! J; J
         
4 @! S1 b- ^/ s0 X  p0 ^                flags = SWO_EventFlags;3 l  c; i" O3 A
                SWO_EventFlags = 0U;
: Z  N; P! I: [, S$ F! b8 @    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
  `3 G6 k5 i- R5 f% ]1 F* C      timeout = SWO_STREAM_TIMEOUT;$ |1 @2 @1 ?2 |; A2 k
      timeWait=DWT->CYCCNT;
& R/ Y7 [( l, p) x. J    } else {9 @' n7 q4 y4 N7 Z& X7 D$ s4 a
      timeout = osWaitForever;
3 r- h* V4 n* T6 ]1 @  ]2 _      flags   = osFlagsErrorTimeout;; X  R. a1 T! e' S
    }9 m$ i' W* v4 ~2 _2 I- `& [/ X
    if (TransferBusy == 0U) {& O  |" h4 ?  r, k  W
      count = GetTraceCount();
" E7 A6 P0 s+ x2 e) d      if (count != 0U) {+ r3 C& K0 y1 `
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);4 Q4 _) U( ?' I' p. k
        n = SWO_BUFFER_SIZE - index;
8 {% d1 y- p- o7 z# }' A        if (count > n) {; F0 S* R, q2 ^" g7 ]7 E
          count = n;
+ z9 @1 x! {$ k' [* {! g6 @                                        ( j* S9 V. Q8 H; p1 o( _4 H. _; K" T7 c
        }
6 S8 |$ _8 B, ~                                if(count>USB_BLOCK_SIZE)
$ c" }; F( C: o  B5 b7 \0 S6 ]                                        count=USB_BLOCK_SIZE;( o1 o% |9 K/ V
        if (flags != osFlagsErrorTimeout) {, F  [3 k; t' Q- ^) `0 W) Z* }& `
          i = index & (USB_BLOCK_SIZE - 1U);
: y' W0 L9 U7 V          if (i == 0U) {
6 e" @+ [) r1 q: B/ i            count &= ~(USB_BLOCK_SIZE - 1U);
9 {$ P: V5 w( t0 `, f          } else {
. P! Z2 d8 d" C4 x  q            n = USB_BLOCK_SIZE - i;! U) J/ n3 ~1 C7 p
            if (count >= n) {
" c/ b6 e1 O+ h& N* n# @              count = n;
. n  x( [* B4 Q4 V            } else {
0 i0 F$ P' Q/ C              count = 0U;% x2 A# M) G& u0 ]7 M1 ?4 G4 F
            }/ O  u! d  v0 n9 M8 B$ M' q
          }6 U5 b7 K& y/ G+ E1 d% k- L# A
        }
2 @  V& U- h" b! `% E% O        if (count != 0U) {
1 o4 _0 R7 _5 [) J1 A0 @; n          TransferSize = count;4 Q: g; a' e8 f0 |
          TransferBusy = 1U;$ o* i8 s7 O# g' e( {% N( f- w0 v
          SWO_QueueTransfer(&TraceBuf[index], count);( ~+ T8 F- N$ y, p* _& A/ F
        }4 y% m- z3 t) J& ]
      }
9 @: u# A5 z( r- W8 a) f  y6 ?" o    }1 }6 K& Q( w4 _" O3 ?$ V8 `
  //}
: G+ Q5 l+ \* F$ a3 J                return 0;
; Y2 ~$ Z7 B* z. f}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了% G- I1 M1 w; C7 o

5 ^: u& z- M% z* @* ?& G9 pCDC部分暂时还没加入,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 g. r. `1 r/ k, C1 ^" \' a  ^; F! K( v- ]( o% Q) u

, v3 a6 }/ H3 V/ vint main(void)
. Y9 V( M1 P" i! d{/ e0 Q4 y% s+ F9 U# N0 w  E0 |
  DWT_Init();
0 e1 ?6 y, g1 @) @- H6 y$ h        DAP_Setup();
; o- [% @' v+ ?+ Z+ M2 E( k  USB_Interrupts_Config();
' @3 R  N1 @4 {! V7 W  y; j  Set_USBClock();
$ ?4 _  w! y+ e  USB_Init();$ G4 b% ?4 d, @2 p! }4 r0 t. D
        //TIM3_Init(35999,0);) G1 b  u1 [3 P  @% n7 w
        //TIM_Cmd(TIM3,ENABLE);
1 g; Z: ~. D: z3 x- `, q        . i( t4 g# O3 n, {0 o' _/ m& x, J7 p
        
4 J9 o" X4 \# g' U0 y  while (1)
8 _, p6 G( i' a0 ]  {. q1 N6 v+ q0 v8 I' }" r
                DAP_Thread();
9 j0 _* f- T( Q+ u9 o+ [# i                #if (SWO_STREAM != 0)5 M+ ]3 l+ O1 N+ k7 t- V/ v" v: [
                SWO_Thread();
; n; a! E; ]# n5 H1 {+ ~' w                #endif2 Z, ]$ d& I0 i( P' W
  }
- H+ {; b6 l2 l1 J- r0 m}
6 j& s: X( T$ B. {+ v8 Q
( V+ y- K6 n/ W  [5 T3 s4 r5 }对于DAP_config.h的IO配置我是这样弄的% P  ]2 w; a! D4 u
///@}( u8 Z8 s7 j% F. X
// Debug Port I/O Pins, U% N' r( Y: M% j+ N/ a
3 V. z+ V7 V: I, U+ T
// SWCLK/TCK Pin                GPIOA[6]' j3 g- A" H; B& H) [
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198) z8 L* A1 T8 X! I, v$ V7 P
#define SWCLK_TCK_IN                               *( uint32_t*)0x42210118
( D) r3 B3 G+ a7 _/ t" x/ o
/ A; J3 ~, ~, z// SWDIO/TMS Pin                GPIOA[7]
# k7 i: ~* q! w4 \#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C3 g$ H4 a2 a$ F' ]- T! U; R( U
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C
" l, x3 W3 {& O6 w6 k
7 _' |0 w6 o0 f& {9 S0 E$ m" @// SWDIO Output Enable Pin      GPIOA[7]6 U8 l' J4 q& {, m4 W  C+ b
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \) N" e9 F7 D3 e2 W
                                                                                                                                *(uint32_t*)0x42210070 = 1; \1 w/ b5 e. s9 B3 H8 j9 c4 O9 `# W# p
                                                                                                                                *(uint32_t*)0x42210074 = 1; \
* W4 k! N! k. p/ R7 [                                                                                                                                *(uint32_t*)0x42210078 = 0; \
& ]- P7 g8 H$ F6 z                                                                                                                                *(uint32_t*)0x4221007C = 0;}; _- c$ k$ c8 T5 _

' c/ j! P5 E3 K1 E: p3 H#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \
  g/ Y1 Z/ V  S& q" @                                                                                                                                *(uint32_t*)0x42210070 = 0; \
8 ]# S4 E! \! @' N; o/ d, R                                                                                                                                *(uint32_t*)0x42210074 = 0; \
, ]1 h9 C) `5 Y# E3 S                                                                                                                                *(uint32_t*)0x42210078 = 0; \
$ Z% ^6 J: B4 I( }5 O                                                                                                                                *(uint32_t*)0x4221007C = 1; }3 D! e3 a" O) s
. z' s8 ~, N: ]5 k4 l, W) T" y- F! g
// TDI Pin                      GPIOA[8]  D9 N3 H* z' \+ u5 T  _6 ~. ~. L: @
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0' s! J" m" \$ _. p+ g2 h" I9 l
#define TDI_IN                                     *(volatile uint32_t*)0x42210120
/ b0 A3 H; W0 l) C7 |, n( |
" O' _0 [& C; R# K  a// TDO Pin                      GPIOA[10]- w4 N3 R2 |" x$ f5 X# b0 Z/ L6 T
#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8
; F  `& C0 d( k8 t#define TDO_IN                                     *(volatile uint32_t*)0x422101286 k+ H! N4 b$ x4 P# R

# E5 l1 Y1 [# H" {// nTRST Pin                    GPIOB[3]& S; Z5 V. `/ L# h
#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C/ Y. K( }7 H7 }$ S+ _
#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C: Z- X' f1 d8 [( ~1 M+ V. N

8 g8 c! M( I2 J# h: |" J: `// nRESET Pin                   GPIOB[4]2 c9 d5 M. x& S0 P3 @
#define nRESET_OUT                                 *(volatile uint32_t*)0x422181907 t4 C6 h* b0 Y& p; ^; v  D
#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
7 D( |* d5 T& @% S: f. c6 [
- g; |$ p1 G7 Y( B8 c) }// nRESET Output Enable Pin     GPIOB[4]) s/ z" h, ]5 V9 N: f1 i8 h
#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \
$ \2 _  {2 {( k0 f, ^                                                                                                                                *(uint32_t*)0x42218040 = 1; \- G- Y% X; q1 \
                                                                                                                                *(uint32_t*)0x42218044 = 1; \
9 D" H0 e6 i" w! x& M( r$ M                                                                                                                                *(uint32_t*)0x42218048 = 0; \% t4 ^2 z8 S3 Y9 v
                                                                                                                                *(uint32_t*)0x4221804C = 0; } 2 D: {1 p" A! {) y1 G8 K9 X

6 |' m* i* P9 m* Y6 Z#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \
' k1 g9 Q% `$ o+ ^2 p                                                                                                                                *(uint32_t*)0x42218040 = 0; \
7 b# O$ W2 F1 g                                                                                                                                *(uint32_t*)0x42218044 = 0; \3 d: y0 ]3 _2 d
                                                                                                                                *(uint32_t*)0x42218048 = 0;\
7 o9 w9 J5 Q  X0 `7 O0 L                                                                                                                                *(uint32_t*)0x4221804C = 1; }
0 d. P' N5 n# F4 e, P9 q' m9 m' H5 W

: w# C. J+ l( R5 K// Debug Unit LEDs; Z+ m; @3 X7 T' L9 y" _3 r+ D* i
5 @/ u- w5 x4 w) @5 ^
// Connected LED                GPIOC[13]
! E9 B" z/ d, a3 p% s#define LED_OUT                                                      *(volatile uint32_t*)0x422201B4
9 x7 X% N3 A. ]" ~- `( y#define LED_IN                                                       *(volatile uint32_t*)0x42220134
/ x( W+ |# h5 H# M: M" H! V8 m5 @& }, Q& U6 J( t
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
& N& M' e0 j% s! I6 Y6 k                                                                                                                                *(uint32_t*)0x422200D0 = 0; \) k+ Z) a) B1 A+ q/ h9 N6 f
                                                                                                                                *(uint32_t*)0x422200D4 = 0; \
* u% o8 F* G2 |4 Q" D7 E3 D1 V                                                                                                                                *(uint32_t*)0x422200D8 = 0; \' v# R- @+ _6 w! i; C/ s  `
                                                                                                                                *(uint32_t*)0x422200DC = 1; }
' h: r( g& C! O5 p* b// Target Running LED           Not available
  ?3 ]: Q" O6 L* [/ U4 s( v8 q! j. k- w% `
// SWCLK/TCK I/O pin -------------------------------------. f) M/ Z1 L) y# c7 \' Y; z

6 @; ~& b% q3 i# F/ P! ^/** SWCLK/TCK I/O pin: Get Input.' L; U( O# r5 y1 V
\return Current status of the SWCLK/TCK DAP hardware I/O pin.0 p! i! [3 }7 B) |9 o
*/
- X% ]7 I& ^# O: e__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {/ }* L6 E9 a- |
  return (SWCLK_TCK_IN);  ~! z" n$ l+ b+ J. l' R
}* b: L! H) W( x* R
- J$ `/ M) x) d( ]
/** SWCLK/TCK I/O pin: Set Output to High.
  K6 a# _. I$ Y1 K2 T* ZSet the SWCLK/TCK DAP hardware I/O pin to high level.2 j. N6 p. m; X: G  L1 L9 j% z
*/0 D2 H0 [# A1 B2 D0 x+ n8 P
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {
7 @( V8 q! V$ N! U  z4 k+ M  x  SWCLK_TCK_OUT = 1;
: K( t, s, s' n. d/ q( u7 c}& M. K! `: f$ \* v9 H
/ @. h4 j) \" p2 j. M
/** SWCLK/TCK I/O pin: Set Output to Low.
1 K4 P( D+ U. I3 j$ @* M+ gSet the SWCLK/TCK DAP hardware I/O pin to low level.$ r/ e" y9 }2 N' T7 D7 }
*/, G" v/ i. W8 ^! h' N5 K! x
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {/ M( j3 y9 d" X% P1 F* C
  SWCLK_TCK_OUT = 0;
6 A* r/ x% g, t# D}
' Z4 B" U( ~3 K" T  @
9 c; g2 [% t5 @
6 L: W. {% G. Z, J9 K; C% r* H// SWDIO/TMS Pin I/O --------------------------------------, ]2 B; Z, s$ a
8 u2 D2 n5 o* C" Z
/** SWDIO/TMS I/O pin: Get Input.
5 {4 A/ s2 R# Z0 Q- ^# P. A* J\return Current status of the SWDIO/TMS DAP hardware I/O pin.0 r. ~1 T, K/ F% R, R5 C
*/
! N# ^! t% d5 A3 [__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
. P" Y" {1 ]8 W6 k% x, u" Q; N  return (SWDIO_TMS_IN);
4 Y8 `. H4 {6 k3 o7 o7 Z}
" F) H7 {; w3 v; V& v
5 o3 u" `- T3 N3 T$ k/** SWDIO/TMS I/O pin: Set Output to High.& n2 l. M4 n/ Z1 l0 g
Set the SWDIO/TMS DAP hardware I/O pin to high level., N( v: l* u+ w1 L9 f7 m
*/
4 D! J' C9 ^; Y$ Z5 N, |__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {: \  g- h1 `! ^9 x
  SWDIO_TMS_OUT = 1;4 O9 S2 {- W3 r$ o6 f
}; k  b4 [0 Q- V) J& Y( J2 ]# G
) L6 d+ ~0 a: E
/** SWDIO/TMS I/O pin: Set Output to Low.
; ^7 s! u. J8 W7 Q1 k; f5 P3 _8 E/ lSet the SWDIO/TMS DAP hardware I/O pin to low level.- H) s' N% ?$ f+ V2 |
*/1 ?, @' ]/ g8 [, J) b5 n
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {
" @: S$ k7 S) H9 x  SWDIO_TMS_OUT = 0;+ ?  p8 J1 D2 ^. |8 s. V$ e9 i
}9 O; r) B  \9 v* @* Q

. x1 X! t! A# Y% K/ i' {/** SWDIO I/O pin: Get Input (used in SWD mode only).
2 A' p1 P4 g' w\return Current status of the SWDIO DAP hardware I/O pin." g# U; {1 i, t
*/( S( A! ?2 `# Y0 v0 w2 \( w7 L! z
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
5 d2 Q1 `9 {5 ~  {  return (SWDIO_TMS_IN);
* x# k8 h$ y; O$ r* r6 ^. ?}
0 f& T$ y; g& @5 s' P. u' V( M8 y( |, e8 o$ J1 c6 g2 a
/** SWDIO I/O pin: Set Output (used in SWD mode only).; U& s9 [; R+ x4 v& `5 W
\param bit Output value for the SWDIO DAP hardware I/O pin.
$ `1 @  F2 y1 O( I; Z) }*/
) o; h& M( i1 I9 Z7 c6 v2 x7 f__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
0 \2 b4 B0 G6 O! z$ t  _/ ^& k' Z  SWDIO_TMS_OUT = bit;
$ c: M' Y! @' e7 N  T}
; W* z7 ^2 ?! `6 h# L4 A/ Z( S& J2 O' d' j6 X
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
% z; f5 ?) F( D$ B- y) MConfigure the SWDIO DAP hardware I/O pin to output mode. This function is- P* _; ^) `# p+ i( e8 e- R, a+ {
called prior \ref PIN_SWDIO_OUT function calls.
) t4 P0 M" e: R! s; @*/% n- M8 \9 j2 Z% C+ ]* I& ]
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {
+ T& \0 e5 l/ S. A5 n* N2 g  SWDIO_Output();
& K4 \- m! o! X# s+ }}
1 D, T0 P. y( N2 B- S5 v- u2 ~' x5 V" z( k. J
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
# E6 F  X9 M: dConfigure the SWDIO DAP hardware I/O pin to input mode. This function is  a8 P0 O% P& I. E- l, B6 ]& E
called prior \ref PIN_SWDIO_IN function calls.
, B8 N$ j3 W% x1 L8 X! K*/
5 T! ]/ d, O  l9 L* N! a__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {" h2 F0 n. }- Y
  SWDIO_Input();& d/ m( {$ D5 r' q. E# b
}, U) ?5 C8 u' A. Y
( B5 @% M# [2 N3 ^+ c1 n
楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的
+ p/ `% m# h1 |即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下
* q( f& ^# Y: b; m5 T5 ^; y
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版