硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3937|回复: 5
收起左侧

[玩转DAPLINK] 新版CMSIS-DAP V2.0.1增加了一个DAP 硬件UART的玩法,类似SWO引脚的另一种方式

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2021-5-27 08:53:30 | 显示全部楼层 |阅读模式
CMSIS V5.8.0软件包下个月应该就正式发布了,当前Github上已经更新,估计还有些待整理。

https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DAP/Firmware

在DAP协议上增加了个串口通信

3.png


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
 楼主| 发表于 2021-5-27 09:00:09 | 显示全部楼层
  1. /*
  2. * Copyright (c) 2021 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * ----------------------------------------------------------------------
  19. *
  20. * $Date:        1. March 2021
  21. * $Revision:    V1.0.0
  22. *
  23. * Project:      CMSIS-DAP Source
  24. * Title:        UART.c CMSIS-DAP UART
  25. *
  26. *---------------------------------------------------------------------------*/

  27. #include "DAP_config.h"
  28. #include "DAP.h"

  29. #if (DAP_UART != 0)

  30. #ifdef DAP_FW_V1
  31. #error "UART Communication Port not supported in DAP V1!"
  32. #endif

  33. #include "Driver_USART.h"

  34. #include "cmsis_os2.h"
  35. #include <string.h>

  36. #define UART_TX_BUF_SIZE    1024U   /* Uart Tx Buffer (must be 2^n) */
  37. #define UART_RX_BUF_SIZE    1024U   /* Uart Rx Buffer (must be 2^n) */
  38. #define UART_RX_BLOCK_SIZE    32U   /* Uart Rx Block Size (must be 2^n) */
  39. #define UART_MAX_XFER_NUM    509U

  40. // USART Driver
  41. #define _USART_Driver_(n)  Driver_USART##n
  42. #define  USART_Driver_(n) _USART_Driver_(n)
  43. extern ARM_DRIVER_USART    USART_Driver_(DAP_UART_DRIVER);
  44. #define pUSART           (&USART_Driver_(DAP_UART_DRIVER))

  45. // UART Configuration
  46. static uint8_t  UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
  47. static uint8_t  UartControl   = 0U;
  48. static uint32_t UartBaudrate  = 115200U;

  49. // UART TX Buffer
  50. static uint8_t UartTxBuf[UART_TX_BUF_SIZE];
  51. static volatile uint32_t UartTxIndexI = 0U;
  52. static volatile uint32_t UartTxIndexO = 0U;

  53. // UART RX Buffer
  54. static uint8_t UartRxBuf[UART_RX_BUF_SIZE];
  55. static volatile uint32_t UartRxIndexI = 0U;
  56. static volatile uint32_t UartRxIndexO = 0U;

  57. // Uart Errors
  58. static volatile uint8_t UartRxDataLost   = 0U;
  59. static volatile uint8_t UartFramingError = 0U;
  60. static volatile uint8_t UartParityError  = 0U;

  61. // UART Transmit
  62. static uint32_t UartTxNum = 0U;

  63. // Function prototypes
  64. static uint32_t UART_Start   (void);
  65. static uint32_t UART_Stop    (void);
  66. static void     UART_Send    (void);
  67. static void     UART_Receive (void);


  68. // USART Driver Callback function
  69. //   event: event mask
  70. static void USART_Callback (uint32_t event) {
  71.   if (event &  ARM_USART_EVENT_SEND_COMPLETE) {
  72.     UartTxIndexO += UartTxNum;
  73.     UART_Send();
  74.   }
  75.   if (event &  ARM_USART_EVENT_RECEIVE_COMPLETE) {
  76.     UartRxIndexI += UART_RX_BLOCK_SIZE;
  77.     UART_Receive();
  78.   }
  79.   if (event &  ARM_USART_EVENT_RX_OVERFLOW) {
  80.     UartRxDataLost = 1U;
  81.   }
  82.   if (event &  ARM_USART_EVENT_RX_FRAMING_ERROR) {
  83.     UartFramingError = 1U;
  84.   }
  85.   if (event &  ARM_USART_EVENT_RX_PARITY_ERROR) {
  86.     UartParityError = 1U;
  87.   }
  88. }

  89. // Start UART
  90. //   return: 1 - Success, 0 - Error
  91. static uint32_t UART_Start (void) {
  92.   int32_t status;
  93.   uint32_t ret;

  94.   UartTxNum = 0U;

  95.   UartTxIndexI = 0U;
  96.   UartTxIndexO = 0U;
  97.   UartRxIndexI = 0U;
  98.   UartRxIndexO = 0U;

  99.   status = pUSART->Initialize(USART_Callback);

  100.   if (status == ARM_DRIVER_OK) {
  101.     status = pUSART->PowerControl(ARM_POWER_FULL);
  102.   }

  103.   if (status == ARM_DRIVER_OK) {
  104.     status = pUSART->Control (UartControl |
  105.                               ARM_USART_MODE_ASYNCHRONOUS |
  106.                               ARM_USART_FLOW_CONTROL_NONE,
  107.                               UartBaudrate);
  108.   }

  109.   if (status == ARM_DRIVER_OK) {
  110.     UART_Receive();
  111.     pUSART->Control (ARM_USART_CONTROL_TX, 1);
  112.     pUSART->Control (ARM_USART_CONTROL_RX, 1);
  113.   }

  114.   if (status != ARM_DRIVER_OK) {
  115.     pUSART->PowerControl(ARM_POWER_OFF);
  116.     pUSART->Uninitialize();
  117.   }

  118.   if (status == ARM_DRIVER_OK) {
  119.     ret = 1U;
  120.   } else {
  121.     ret = 0U;
  122.   }

  123.   return (ret);
  124. }

  125. // Stop UART
  126. //   return: 1 - Success, 0 - Error
  127. static uint32_t UART_Stop (void) {
  128.   UartTxIndexI = 0U;
  129.   UartTxIndexO = 0U;
  130.   UartRxIndexI = 0U;
  131.   UartRxIndexO = 0U;

  132.   pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
  133.   pUSART->Control(ARM_USART_ABORT_SEND, 0U);
  134.   pUSART->PowerControl(ARM_POWER_OFF);
  135.   pUSART->Uninitialize();

  136.   return (1U);
  137. }

  138. // Send available data to target via UART
  139. static void UART_Send (void) {
  140.   uint32_t count;
  141.   uint32_t index;

  142.   count = UartTxIndexI - UartTxIndexO;
  143.   index = UartTxIndexO & (UART_TX_BUF_SIZE - 1);

  144.   if (count != 0U) {
  145.     if ((index + count) < UART_TX_BUF_SIZE) {
  146.       UartTxNum = count;
  147.     } else {
  148.       UartTxNum = UART_TX_BUF_SIZE - index;
  149.     }
  150.     pUSART->Send(&UartTxBuf[index], UartTxNum);
  151.   }
  152. }

  153. // Receive data from target via UART
  154. static void UART_Receive (void) {
  155.   uint16_t num;
  156.   uint32_t count;
  157.   uint32_t index;

  158.   count = UartRxIndexI - UartRxIndexO;
  159.   index = UartRxIndexI & (UART_RX_BUF_SIZE - 1);
  160.   num   =  UART_RX_BLOCK_SIZE;

  161.   if ((UART_RX_BUF_SIZE - count) >= num) {
  162.     pUSART->Receive(&UartRxBuf[index], num);
  163.   }
  164. }

  165. // Process UART Transport command and prepare response
  166. //   request:  pointer to request data
  167. //   response: pointer to response data
  168. //   return:   number of bytes in response (lower 16 bits)
  169. //             number of bytes in request (upper 16 bits)
  170. uint32_t UART_Transport (const uint8_t *request, uint8_t *response) {
  171.   uint8_t  transport;
  172.   uint32_t result = 0U;

  173.   transport = *request;
  174.   switch (transport) {
  175.     case DAP_UART_TRANSPORT_USB_COM_PORT:
  176. #if (DAP_UART_USB_COM_PORT != 0U)
  177.       if (UartTransport == DAP_UART_TRANSPORT_DAP_COMMAND) {
  178.         result = UART_Stop();
  179.         USB_COM_PORT_Activate(1U);
  180.       } else {
  181.         result = 1U;
  182.       }
  183.       UartTransport = transport;
  184. #endif
  185.       break;
  186.     case DAP_UART_TRANSPORT_DAP_COMMAND:
  187.       if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
  188. #if (DAP_UART_USB_COM_PORT != 0U)
  189.         USB_COM_PORT_Activate(0U);
  190. #endif
  191.         result = UART_Start();
  192.       } else {
  193.         result = 1U;
  194.       }
  195.       UartTransport = transport;
  196.       break;
  197.     default:
  198.       result = 0U;
  199.       break;
  200.   }

  201.   if (result != 0U) {
  202.     *response = DAP_OK;
  203.   } else {
  204.     *response = DAP_ERROR;
  205.   }

  206.   return ((1U << 16) | 1U);
  207. }

  208. // Process UART Configure command and prepare response
  209. //   request:  pointer to request data
  210. //   response: pointer to response data
  211. //   return:   number of bytes in response (lower 16 bits)
  212. //             number of bytes in request (upper 16 bits)
  213. uint32_t UART_Configure (const uint8_t *request, uint8_t *response) {
  214.   uint8_t  control, status;
  215.   uint32_t baudrate;
  216.   int32_t  result;

  217.   status   = 0U;
  218.   control  = *request;
  219.   baudrate = (uint32_t)(*(request+1) <<  0) |
  220.              (uint32_t)(*(request+2) <<  8) |
  221.              (uint32_t)(*(request+3) << 16) |
  222.              (uint32_t)(*(request+4) << 24);

  223.   if (UartTransport == DAP_UART_TRANSPORT_DAP_COMMAND) {
  224.     result = pUSART->Control (control |
  225.                               ARM_USART_MODE_ASYNCHRONOUS |
  226.                               ARM_USART_FLOW_CONTROL_NONE,
  227.                               baudrate);
  228.     switch (result) {
  229.       case ARM_USART_ERROR_BAUDRATE:
  230.         status = 0U;
  231.         baudrate = 0U;
  232.         break;
  233.       case ARM_USART_ERROR_DATA_BITS:
  234.         status = (1U << 0);
  235.         break;
  236.       case ARM_USART_ERROR_STOP_BITS:
  237.         status = (1U << 1);
  238.         break;
  239.       case ARM_USART_ERROR_PARITY:
  240.         status = (1U << 2);
  241.         break;
  242.     }
  243.   }

  244.   if ((status == 0U) && (baudrate != 0U)) {
  245.     UartControl = control;
  246.     UartBaudrate = baudrate;
  247.   }

  248.   *response++ = status;
  249.   *response++ = (uint8_t)(baudrate >>  0);
  250.   *response++ = (uint8_t)(baudrate >>  8);
  251.   *response++ = (uint8_t)(baudrate >> 16);
  252.   *response   = (uint8_t)(baudrate >> 24);

  253.   return ((5U << 16) | 5U);
  254. }

  255. // Process UART Transfer command and prepare response
  256. //   request:  pointer to request data
  257. //   response: pointer to response data
  258. //   return:   number of bytes in response (lower 16 bits)
  259. //             number of bytes in request (upper 16 bits)
  260. uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) {
  261.   uint16_t status = 0U;
  262.   uint32_t count, index;
  263.   uint32_t tx_num, rx_num, num;
  264.   uint8_t * data;

  265.   if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
  266.     return (0U);
  267.   }

  268.   // TX Data
  269.   tx_num = ((uint16_t)(*(request+0) <<  0)  |
  270.             (uint16_t)(*(request+1) <<  8));
  271.   data = (uint8_t *)((uint32_t)request) + 2;

  272.   if (tx_num > UART_MAX_XFER_NUM) {
  273.     tx_num = UART_MAX_XFER_NUM;
  274.   }

  275.   count = UartTxIndexI - UartTxIndexO;
  276.   index = UartTxIndexI & (UART_TX_BUF_SIZE - 1);

  277.   if ((UART_TX_BUF_SIZE - count) >= tx_num) {
  278.     if ((index + tx_num) < UART_TX_BUF_SIZE) {
  279.       memcpy(&UartTxBuf[index], data, tx_num);
  280.     } else {
  281.       num = UART_TX_BUF_SIZE - index;
  282.       memcpy(&UartTxBuf[index], data, num);
  283.       memcpy(&UartTxBuf[0], data + num, tx_num - num);
  284.     }
  285.     UartTxIndexI += tx_num;

  286.     if (pUSART->GetStatus().tx_busy == 0U) {
  287.       UART_Send();
  288.     }
  289.   } else {
  290.     // Tx Data lost
  291.     status |= DAP_UART_TRANSFER_TX_DATA_LOST;
  292.   }
  293.   if ((UART_TX_BUF_SIZE - count) < UART_MAX_XFER_NUM) {
  294.     // Can't accept next full TX packet
  295.     status |= DAP_UART_TRANSFER_TX_BUSY;
  296.   }

  297.   // RX Data
  298.   rx_num  = UartRxIndexI - UartRxIndexO;
  299.   rx_num += pUSART->GetRxCount();
  300.   data = response + 2;
  301.   index = UartRxIndexO & (UART_RX_BUF_SIZE - 1);

  302.   if (rx_num > UART_MAX_XFER_NUM) {
  303.     rx_num = UART_MAX_XFER_NUM;
  304.   }
  305.   if ((index + rx_num) < UART_RX_BUF_SIZE) {
  306.     memcpy(data, &UartRxBuf[index], rx_num);
  307.   } else {
  308.     num = UART_RX_BUF_SIZE - index;
  309.     memcpy(data, &UartRxBuf[index], num);
  310.     memcpy(data + num, &UartRxBuf[0], rx_num - num);
  311.   }
  312.   UartRxIndexO += rx_num;

  313.   if (pUSART->GetStatus().rx_busy == 0U) {
  314.     UART_Receive();
  315.   }

  316.   if (UartRxDataLost == 1U) {
  317.     UartRxDataLost = 0U;
  318.     status |= DAP_UART_TRANSFER_RX_DATA_LOST;
  319.   }
  320.   if (UartFramingError == 1U) {
  321.     UartFramingError = 0U;
  322.     status |= DAP_UART_TRANSFER_FRAMING_ERROR;
  323.   }
  324.   if (UartParityError == 1U) {
  325.     UartParityError = 0U;
  326.     status |= DAP_UART_TRANSFER_PARITY_ERROR;
  327.   }

  328.   status |= rx_num;

  329.   *response++ = (uint8_t)(status >> 0);
  330.   *response++ = (uint8_t)(status >> 8);

  331.   return (((2U + tx_num) << 16) | (2U + rx_num));
  332. }

  333. #endif /* DAP_UART */
复制代码


回复

使用道具 举报

44

主题

563

回帖

700

积分

金牌会员

积分
700
发表于 2021-5-27 20:34:07 | 显示全部楼层
H7-TOOL可以添加这个功能啊,调试和串口同时还是很方便的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
 楼主| 发表于 2021-5-27 20:58:32 | 显示全部楼层
ou513 发表于 2021-5-27 20:34
H7-TOOL可以添加这个功能啊,调试和串口同时还是很方便的

现在的TOOL就支持,DAPLINK调试和HID高速虚拟串口同时使用。
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2021-5-28 08:07:26 | 显示全部楼层
预感MDK要发布新版了,这个功能应该要配合MDK新调试组件一起用,像ITM, EVENT RECORDER的方式
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
 楼主| 发表于 2021-5-28 09:42:57 | 显示全部楼层
byccc 发表于 2021-5-28 08:07
预感MDK要发布新版了,这个功能应该要配合MDK新调试组件一起用,像ITM, EVENT RECORDER的方式

下个月新的CMSIS软件包要发布,MDK应该也快了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 18:33 , Processed in 0.187398 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表