| 1 | /*
|
|---|
| 2 | * Copyright (c) 2013-2022 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: 26. April 2022
|
|---|
| 21 | * $Revision: V2.1.1
|
|---|
| 22 | *
|
|---|
| 23 | * Project: CMSIS-DAP Source
|
|---|
| 24 | * Title: DAP.c CMSIS-DAP Commands
|
|---|
| 25 | *
|
|---|
| 26 | *---------------------------------------------------------------------------*/
|
|---|
| 27 |
|
|---|
| 28 | #include <string.h>
|
|---|
| 29 | #include "DAP_config.h"
|
|---|
| 30 | #include "DAP.h"
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 | #if (DAP_PACKET_SIZE < 64U)
|
|---|
| 34 | #error "Minimum Packet Size is 64!"
|
|---|
| 35 | #endif
|
|---|
| 36 | #if (DAP_PACKET_SIZE > 32768U)
|
|---|
| 37 | #error "Maximum Packet Size is 32768!"
|
|---|
| 38 | #endif
|
|---|
| 39 | #if (DAP_PACKET_COUNT < 1U)
|
|---|
| 40 | #error "Minimum Packet Count is 1!"
|
|---|
| 41 | #endif
|
|---|
| 42 | #if (DAP_PACKET_COUNT > 255U)
|
|---|
| 43 | #error "Maximum Packet Count is 255!"
|
|---|
| 44 | #endif
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 | // Clock Macros
|
|---|
| 48 | #define MAX_SWJ_CLOCK(delay_cycles) \
|
|---|
| 49 | ((CPU_CLOCK/2U) / (IO_PORT_WRITE_CYCLES + delay_cycles))
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 | DAP_Data_t DAP_Data; // DAP Data
|
|---|
| 53 | volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | static const char DAP_FW_Ver [] = DAP_FW_VER;
|
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 | // Common clock delay calculation routine
|
|---|
| 60 | // clock: requested SWJ frequency in Hertz
|
|---|
| 61 | static void Set_Clock_Delay(uint32_t clock) {
|
|---|
| 62 | uint32_t delay;
|
|---|
| 63 |
|
|---|
| 64 | if (clock >= MAX_SWJ_CLOCK(DELAY_FAST_CYCLES)) {
|
|---|
| 65 | DAP_Data.fast_clock = 1U;
|
|---|
| 66 | DAP_Data.clock_delay = 1U;
|
|---|
| 67 | } else {
|
|---|
| 68 | DAP_Data.fast_clock = 0U;
|
|---|
| 69 |
|
|---|
| 70 | delay = ((CPU_CLOCK/2U) + (clock - 1U)) / clock;
|
|---|
| 71 | if (delay > IO_PORT_WRITE_CYCLES) {
|
|---|
| 72 | delay -= IO_PORT_WRITE_CYCLES;
|
|---|
| 73 | delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES;
|
|---|
| 74 | } else {
|
|---|
| 75 | delay = 1U;
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | DAP_Data.clock_delay = delay;
|
|---|
| 79 | }
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 | // Get DAP Information
|
|---|
| 84 | // id: info identifier
|
|---|
| 85 | // info: pointer to info data
|
|---|
| 86 | // return: number of bytes in info data
|
|---|
| 87 | static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
|
|---|
| 88 | uint8_t length = 0U;
|
|---|
| 89 |
|
|---|
| 90 | switch (id) {
|
|---|
| 91 | case DAP_ID_VENDOR:
|
|---|
| 92 | length = DAP_GetVendorString((char *)info);
|
|---|
| 93 | break;
|
|---|
| 94 | case DAP_ID_PRODUCT:
|
|---|
| 95 | length = DAP_GetProductString((char *)info);
|
|---|
| 96 | break;
|
|---|
| 97 | case DAP_ID_SER_NUM:
|
|---|
| 98 | length = DAP_GetSerNumString((char *)info);
|
|---|
| 99 | break;
|
|---|
| 100 | case DAP_ID_DAP_FW_VER:
|
|---|
| 101 | length = (uint8_t)sizeof(DAP_FW_Ver);
|
|---|
| 102 | memcpy(info, DAP_FW_Ver, length);
|
|---|
| 103 | break;
|
|---|
| 104 | case DAP_ID_DEVICE_VENDOR:
|
|---|
| 105 | length = DAP_GetTargetDeviceVendorString((char *)info);
|
|---|
| 106 | break;
|
|---|
| 107 | case DAP_ID_DEVICE_NAME:
|
|---|
| 108 | length = DAP_GetTargetDeviceNameString((char *)info);
|
|---|
| 109 | break;
|
|---|
| 110 | case DAP_ID_BOARD_VENDOR:
|
|---|
| 111 | length = DAP_GetTargetBoardVendorString((char *)info);
|
|---|
| 112 | break;
|
|---|
| 113 | case DAP_ID_BOARD_NAME:
|
|---|
| 114 | length = DAP_GetTargetBoardNameString((char *)info);
|
|---|
| 115 | break;
|
|---|
| 116 | case DAP_ID_PRODUCT_FW_VER:
|
|---|
| 117 | length = DAP_GetProductFirmwareVersionString((char *)info);
|
|---|
| 118 | break;
|
|---|
| 119 | case DAP_ID_CAPABILITIES:
|
|---|
| 120 | info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) |
|
|---|
| 121 | ((DAP_JTAG != 0) ? (1U << 1) : 0U) |
|
|---|
| 122 | ((SWO_UART != 0) ? (1U << 2) : 0U) |
|
|---|
| 123 | ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) |
|
|---|
| 124 | /* Atomic Commands */ (1U << 4) |
|
|---|
| 125 | ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) |
|
|---|
| 126 | ((SWO_STREAM != 0U) ? (1U << 6) : 0U) |
|
|---|
| 127 | ((DAP_UART != 0U) ? (1U << 7) : 0U);
|
|---|
| 128 |
|
|---|
| 129 | info[1] = ((DAP_UART_USB_COM_PORT != 0) ? (1U << 0) : 0U);
|
|---|
| 130 | length = 2U;
|
|---|
| 131 | break;
|
|---|
| 132 | case DAP_ID_TIMESTAMP_CLOCK:
|
|---|
| 133 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 134 | info[0] = (uint8_t)(TIMESTAMP_CLOCK >> 0);
|
|---|
| 135 | info[1] = (uint8_t)(TIMESTAMP_CLOCK >> 8);
|
|---|
| 136 | info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16);
|
|---|
| 137 | info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24);
|
|---|
| 138 | length = 4U;
|
|---|
| 139 | #endif
|
|---|
| 140 | break;
|
|---|
| 141 | case DAP_ID_UART_RX_BUFFER_SIZE:
|
|---|
| 142 | #if (DAP_UART != 0)
|
|---|
| 143 | info[0] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 0);
|
|---|
| 144 | info[1] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 8);
|
|---|
| 145 | info[2] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 16);
|
|---|
| 146 | info[3] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 24);
|
|---|
| 147 | length = 4U;
|
|---|
| 148 | #endif
|
|---|
| 149 | break;
|
|---|
| 150 | case DAP_ID_UART_TX_BUFFER_SIZE:
|
|---|
| 151 | #if (DAP_UART != 0)
|
|---|
| 152 | info[0] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 0);
|
|---|
| 153 | info[1] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 8);
|
|---|
| 154 | info[2] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 16);
|
|---|
| 155 | info[3] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 24);
|
|---|
| 156 | length = 4U;
|
|---|
| 157 | #endif
|
|---|
| 158 | break;
|
|---|
| 159 | case DAP_ID_SWO_BUFFER_SIZE:
|
|---|
| 160 | #if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
|---|
| 161 | info[0] = (uint8_t)(SWO_BUFFER_SIZE >> 0);
|
|---|
| 162 | info[1] = (uint8_t)(SWO_BUFFER_SIZE >> 8);
|
|---|
| 163 | info[2] = (uint8_t)(SWO_BUFFER_SIZE >> 16);
|
|---|
| 164 | info[3] = (uint8_t)(SWO_BUFFER_SIZE >> 24);
|
|---|
| 165 | length = 4U;
|
|---|
| 166 | #endif
|
|---|
| 167 | break;
|
|---|
| 168 | case DAP_ID_PACKET_SIZE:
|
|---|
| 169 | info[0] = (uint8_t)(DAP_PACKET_SIZE >> 0);
|
|---|
| 170 | info[1] = (uint8_t)(DAP_PACKET_SIZE >> 8);
|
|---|
| 171 | length = 2U;
|
|---|
| 172 | break;
|
|---|
| 173 | case DAP_ID_PACKET_COUNT:
|
|---|
| 174 | info[0] = DAP_PACKET_COUNT;
|
|---|
| 175 | length = 1U;
|
|---|
| 176 | break;
|
|---|
| 177 | default:
|
|---|
| 178 | break;
|
|---|
| 179 | }
|
|---|
| 180 |
|
|---|
| 181 | return (length);
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 | // Delay for specified time
|
|---|
| 186 | // delay: delay time in ms
|
|---|
| 187 | void Delayms(uint32_t delay) {
|
|---|
| 188 | delay *= ((CPU_CLOCK/1000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
|
|---|
| 189 | PIN_DELAY_SLOW(delay);
|
|---|
| 190 | }
|
|---|
| 191 |
|
|---|
| 192 |
|
|---|
| 193 | // Process Delay command and prepare response
|
|---|
| 194 | // request: pointer to request data
|
|---|
| 195 | // response: pointer to response data
|
|---|
| 196 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 197 | // number of bytes in request (upper 16 bits)
|
|---|
| 198 | static uint32_t DAP_Delay(const uint8_t *request, uint8_t *response) {
|
|---|
| 199 | uint32_t delay;
|
|---|
| 200 |
|
|---|
| 201 | delay = (uint32_t)(*(request+0)) |
|
|---|
| 202 | (uint32_t)(*(request+1) << 8);
|
|---|
| 203 | delay *= ((CPU_CLOCK/1000000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
|
|---|
| 204 |
|
|---|
| 205 | PIN_DELAY_SLOW(delay);
|
|---|
| 206 |
|
|---|
| 207 | *response = DAP_OK;
|
|---|
| 208 | return ((2U << 16) | 1U);
|
|---|
| 209 | }
|
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 | // Process Host Status command and prepare response
|
|---|
| 213 | // request: pointer to request data
|
|---|
| 214 | // response: pointer to response data
|
|---|
| 215 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 216 | // number of bytes in request (upper 16 bits)
|
|---|
| 217 | static uint32_t DAP_HostStatus(const uint8_t *request, uint8_t *response) {
|
|---|
| 218 |
|
|---|
| 219 | switch (*request) {
|
|---|
| 220 | case DAP_DEBUGGER_CONNECTED:
|
|---|
| 221 | LED_CONNECTED_OUT((*(request+1) & 1U));
|
|---|
| 222 | break;
|
|---|
| 223 | case DAP_TARGET_RUNNING:
|
|---|
| 224 | LED_RUNNING_OUT((*(request+1) & 1U));
|
|---|
| 225 | break;
|
|---|
| 226 | default:
|
|---|
| 227 | *response = DAP_ERROR;
|
|---|
| 228 | return ((2U << 16) | 1U);
|
|---|
| 229 | }
|
|---|
| 230 |
|
|---|
| 231 | *response = DAP_OK;
|
|---|
| 232 | return ((2U << 16) | 1U);
|
|---|
| 233 | }
|
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 | // Process Connect command and prepare response
|
|---|
| 237 | // request: pointer to request data
|
|---|
| 238 | // response: pointer to response data
|
|---|
| 239 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 240 | // number of bytes in request (upper 16 bits)
|
|---|
| 241 | static uint32_t DAP_Connect(const uint8_t *request, uint8_t *response) {
|
|---|
| 242 | uint32_t port;
|
|---|
| 243 |
|
|---|
| 244 | if (*request == DAP_PORT_AUTODETECT) {
|
|---|
| 245 | port = DAP_DEFAULT_PORT;
|
|---|
| 246 | } else {
|
|---|
| 247 | port = *request;
|
|---|
| 248 | }
|
|---|
| 249 |
|
|---|
| 250 | switch (port) {
|
|---|
| 251 | #if (DAP_SWD != 0)
|
|---|
| 252 | case DAP_PORT_SWD:
|
|---|
| 253 | DAP_Data.debug_port = DAP_PORT_SWD;
|
|---|
| 254 | PORT_SWD_SETUP();
|
|---|
| 255 | break;
|
|---|
| 256 | #endif
|
|---|
| 257 | #if (DAP_JTAG != 0)
|
|---|
| 258 | case DAP_PORT_JTAG:
|
|---|
| 259 | DAP_Data.debug_port = DAP_PORT_JTAG;
|
|---|
| 260 | PORT_JTAG_SETUP();
|
|---|
| 261 | break;
|
|---|
| 262 | #endif
|
|---|
| 263 | default:
|
|---|
| 264 | port = DAP_PORT_DISABLED;
|
|---|
| 265 | break;
|
|---|
| 266 | }
|
|---|
| 267 |
|
|---|
| 268 | *response = (uint8_t)port;
|
|---|
| 269 | return ((1U << 16) | 1U);
|
|---|
| 270 | }
|
|---|
| 271 |
|
|---|
| 272 |
|
|---|
| 273 | // Process Disconnect command and prepare response
|
|---|
| 274 | // response: pointer to response data
|
|---|
| 275 | // return: number of bytes in response
|
|---|
| 276 | static uint32_t DAP_Disconnect(uint8_t *response) {
|
|---|
| 277 |
|
|---|
| 278 | DAP_Data.debug_port = DAP_PORT_DISABLED;
|
|---|
| 279 | PORT_OFF();
|
|---|
| 280 |
|
|---|
| 281 | *response = DAP_OK;
|
|---|
| 282 | return (1U);
|
|---|
| 283 | }
|
|---|
| 284 |
|
|---|
| 285 |
|
|---|
| 286 | // Process Reset Target command and prepare response
|
|---|
| 287 | // response: pointer to response data
|
|---|
| 288 | // return: number of bytes in response
|
|---|
| 289 | static uint32_t DAP_ResetTarget(uint8_t *response) {
|
|---|
| 290 |
|
|---|
| 291 | *(response+1) = RESET_TARGET();
|
|---|
| 292 | *(response+0) = DAP_OK;
|
|---|
| 293 | return (2U);
|
|---|
| 294 | }
|
|---|
| 295 |
|
|---|
| 296 |
|
|---|
| 297 | // Process SWJ Pins command and prepare response
|
|---|
| 298 | // request: pointer to request data
|
|---|
| 299 | // response: pointer to response data
|
|---|
| 300 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 301 | // number of bytes in request (upper 16 bits)
|
|---|
| 302 | static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) {
|
|---|
| 303 | #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
|
|---|
| 304 | uint32_t value;
|
|---|
| 305 | uint32_t select;
|
|---|
| 306 | uint32_t wait;
|
|---|
| 307 | uint32_t timestamp;
|
|---|
| 308 |
|
|---|
| 309 | value = (uint32_t) *(request+0);
|
|---|
| 310 | select = (uint32_t) *(request+1);
|
|---|
| 311 | wait = (uint32_t)(*(request+2) << 0) |
|
|---|
| 312 | (uint32_t)(*(request+3) << 8) |
|
|---|
| 313 | (uint32_t)(*(request+4) << 16) |
|
|---|
| 314 | (uint32_t)(*(request+5) << 24);
|
|---|
| 315 |
|
|---|
| 316 | if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
|
|---|
| 317 | if ((value & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
|
|---|
| 318 | PIN_SWCLK_TCK_SET();
|
|---|
| 319 | } else {
|
|---|
| 320 | PIN_SWCLK_TCK_CLR();
|
|---|
| 321 | }
|
|---|
| 322 | }
|
|---|
| 323 | if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
|
|---|
| 324 | if ((value & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
|
|---|
| 325 | PIN_SWDIO_TMS_SET();
|
|---|
| 326 | } else {
|
|---|
| 327 | PIN_SWDIO_TMS_CLR();
|
|---|
| 328 | }
|
|---|
| 329 | }
|
|---|
| 330 | if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
|
|---|
| 331 | PIN_TDI_OUT(value >> DAP_SWJ_TDI);
|
|---|
| 332 | }
|
|---|
| 333 | if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
|
|---|
| 334 | PIN_nTRST_OUT(value >> DAP_SWJ_nTRST);
|
|---|
| 335 | }
|
|---|
| 336 | if ((select & (1U << DAP_SWJ_nRESET)) != 0U){
|
|---|
| 337 | PIN_nRESET_OUT(value >> DAP_SWJ_nRESET);
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | if (wait != 0U) {
|
|---|
| 341 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 342 | if (wait > 3000000U) {
|
|---|
| 343 | wait = 3000000U;
|
|---|
| 344 | }
|
|---|
| 345 | #if (TIMESTAMP_CLOCK >= 1000000U)
|
|---|
| 346 | wait *= TIMESTAMP_CLOCK / 1000000U;
|
|---|
| 347 | #else
|
|---|
| 348 | wait /= 1000000U / TIMESTAMP_CLOCK;
|
|---|
| 349 | #endif
|
|---|
| 350 | #else
|
|---|
| 351 | wait = 1U;
|
|---|
| 352 | #endif
|
|---|
| 353 | timestamp = TIMESTAMP_GET();
|
|---|
| 354 | do {
|
|---|
| 355 | if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
|
|---|
| 356 | if ((value >> DAP_SWJ_SWCLK_TCK) ^ PIN_SWCLK_TCK_IN()) {
|
|---|
| 357 | continue;
|
|---|
| 358 | }
|
|---|
| 359 | }
|
|---|
| 360 | if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
|
|---|
| 361 | if ((value >> DAP_SWJ_SWDIO_TMS) ^ PIN_SWDIO_TMS_IN()) {
|
|---|
| 362 | continue;
|
|---|
| 363 | }
|
|---|
| 364 | }
|
|---|
| 365 | if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
|
|---|
| 366 | if ((value >> DAP_SWJ_TDI) ^ PIN_TDI_IN()) {
|
|---|
| 367 | continue;
|
|---|
| 368 | }
|
|---|
| 369 | }
|
|---|
| 370 | if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
|
|---|
| 371 | if ((value >> DAP_SWJ_nTRST) ^ PIN_nTRST_IN()) {
|
|---|
| 372 | continue;
|
|---|
| 373 | }
|
|---|
| 374 | }
|
|---|
| 375 | if ((select & (1U << DAP_SWJ_nRESET)) != 0U) {
|
|---|
| 376 | if ((value >> DAP_SWJ_nRESET) ^ PIN_nRESET_IN()) {
|
|---|
| 377 | continue;
|
|---|
| 378 | }
|
|---|
| 379 | }
|
|---|
| 380 | break;
|
|---|
| 381 | } while ((TIMESTAMP_GET() - timestamp) < wait);
|
|---|
| 382 | }
|
|---|
| 383 |
|
|---|
| 384 | value = (PIN_SWCLK_TCK_IN() << DAP_SWJ_SWCLK_TCK) |
|
|---|
| 385 | (PIN_SWDIO_TMS_IN() << DAP_SWJ_SWDIO_TMS) |
|
|---|
| 386 | (PIN_TDI_IN() << DAP_SWJ_TDI) |
|
|---|
| 387 | (PIN_TDO_IN() << DAP_SWJ_TDO) |
|
|---|
| 388 | (PIN_nTRST_IN() << DAP_SWJ_nTRST) |
|
|---|
| 389 | (PIN_nRESET_IN() << DAP_SWJ_nRESET);
|
|---|
| 390 |
|
|---|
| 391 | *response = (uint8_t)value;
|
|---|
| 392 | #else
|
|---|
| 393 | *response = 0U;
|
|---|
| 394 | #endif
|
|---|
| 395 |
|
|---|
| 396 | return ((6U << 16) | 1U);
|
|---|
| 397 | }
|
|---|
| 398 |
|
|---|
| 399 |
|
|---|
| 400 | // Process SWJ Clock command and prepare response
|
|---|
| 401 | // request: pointer to request data
|
|---|
| 402 | // response: pointer to response data
|
|---|
| 403 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 404 | // number of bytes in request (upper 16 bits)
|
|---|
| 405 | static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) {
|
|---|
| 406 | #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
|
|---|
| 407 | uint32_t clock;
|
|---|
| 408 | uint32_t delay;
|
|---|
| 409 |
|
|---|
| 410 | clock = (uint32_t)(*(request+0) << 0) |
|
|---|
| 411 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 412 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 413 | (uint32_t)(*(request+3) << 24);
|
|---|
| 414 |
|
|---|
| 415 | if (clock == 0U) {
|
|---|
| 416 | *response = DAP_ERROR;
|
|---|
| 417 | return ((4U << 16) | 1U);
|
|---|
| 418 | }
|
|---|
| 419 |
|
|---|
| 420 | Set_Clock_Delay(clock);
|
|---|
| 421 |
|
|---|
| 422 | *response = DAP_OK;
|
|---|
| 423 | #else
|
|---|
| 424 | *response = DAP_ERROR;
|
|---|
| 425 | #endif
|
|---|
| 426 |
|
|---|
| 427 | return ((4U << 16) | 1U);
|
|---|
| 428 | }
|
|---|
| 429 |
|
|---|
| 430 |
|
|---|
| 431 | // Process SWJ Sequence command and prepare response
|
|---|
| 432 | // request: pointer to request data
|
|---|
| 433 | // response: pointer to response data
|
|---|
| 434 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 435 | // number of bytes in request (upper 16 bits)
|
|---|
| 436 | static uint32_t DAP_SWJ_Sequence(const uint8_t *request, uint8_t *response) {
|
|---|
| 437 | uint32_t count;
|
|---|
| 438 |
|
|---|
| 439 | count = *request++;
|
|---|
| 440 | if (count == 0U) {
|
|---|
| 441 | count = 256U;
|
|---|
| 442 | }
|
|---|
| 443 |
|
|---|
| 444 | #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
|
|---|
| 445 | SWJ_Sequence(count, request);
|
|---|
| 446 | *response = DAP_OK;
|
|---|
| 447 | #else
|
|---|
| 448 | *response = DAP_ERROR;
|
|---|
| 449 | #endif
|
|---|
| 450 |
|
|---|
| 451 | count = (count + 7U) >> 3;
|
|---|
| 452 |
|
|---|
| 453 | return (((count + 1U) << 16) | 1U);
|
|---|
| 454 | }
|
|---|
| 455 |
|
|---|
| 456 |
|
|---|
| 457 | // Process SWD Configure command and prepare response
|
|---|
| 458 | // request: pointer to request data
|
|---|
| 459 | // response: pointer to response data
|
|---|
| 460 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 461 | // number of bytes in request (upper 16 bits)
|
|---|
| 462 | static uint32_t DAP_SWD_Configure(const uint8_t *request, uint8_t *response) {
|
|---|
| 463 | #if (DAP_SWD != 0)
|
|---|
| 464 | uint8_t value;
|
|---|
| 465 |
|
|---|
| 466 | value = *request;
|
|---|
| 467 | DAP_Data.swd_conf.turnaround = (value & 0x03U) + 1U;
|
|---|
| 468 | DAP_Data.swd_conf.data_phase = (value & 0x04U) ? 1U : 0U;
|
|---|
| 469 |
|
|---|
| 470 | *response = DAP_OK;
|
|---|
| 471 | #else
|
|---|
| 472 | *response = DAP_ERROR;
|
|---|
| 473 | #endif
|
|---|
| 474 |
|
|---|
| 475 | return ((1U << 16) | 1U);
|
|---|
| 476 | }
|
|---|
| 477 |
|
|---|
| 478 |
|
|---|
| 479 | // Process SWD Sequence command and prepare response
|
|---|
| 480 | // request: pointer to request data
|
|---|
| 481 | // response: pointer to response data
|
|---|
| 482 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 483 | // number of bytes in request (upper 16 bits)
|
|---|
| 484 | static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) {
|
|---|
| 485 | uint32_t sequence_info;
|
|---|
| 486 | uint32_t sequence_count;
|
|---|
| 487 | uint32_t request_count;
|
|---|
| 488 | uint32_t response_count;
|
|---|
| 489 | uint32_t count;
|
|---|
| 490 |
|
|---|
| 491 | #if (DAP_SWD != 0)
|
|---|
| 492 | *response++ = DAP_OK;
|
|---|
| 493 | #else
|
|---|
| 494 | *response++ = DAP_ERROR;
|
|---|
| 495 | #endif
|
|---|
| 496 | request_count = 1U;
|
|---|
| 497 | response_count = 1U;
|
|---|
| 498 |
|
|---|
| 499 | sequence_count = *request++;
|
|---|
| 500 | while (sequence_count--) {
|
|---|
| 501 | sequence_info = *request++;
|
|---|
| 502 | count = sequence_info & SWD_SEQUENCE_CLK;
|
|---|
| 503 | if (count == 0U) {
|
|---|
| 504 | count = 64U;
|
|---|
| 505 | }
|
|---|
| 506 | count = (count + 7U) / 8U;
|
|---|
| 507 | #if (DAP_SWD != 0)
|
|---|
| 508 | if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
|
|---|
| 509 | PIN_SWDIO_OUT_DISABLE();
|
|---|
| 510 | } else {
|
|---|
| 511 | PIN_SWDIO_OUT_ENABLE();
|
|---|
| 512 | }
|
|---|
| 513 | SWD_Sequence(sequence_info, request, response);
|
|---|
| 514 | if (sequence_count == 0U) {
|
|---|
| 515 | PIN_SWDIO_OUT_ENABLE();
|
|---|
| 516 | }
|
|---|
| 517 | #endif
|
|---|
| 518 | if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
|
|---|
| 519 | request_count++;
|
|---|
| 520 | #if (DAP_SWD != 0)
|
|---|
| 521 | response += count;
|
|---|
| 522 | response_count += count;
|
|---|
| 523 | #endif
|
|---|
| 524 | } else {
|
|---|
| 525 | request += count;
|
|---|
| 526 | request_count += count + 1U;
|
|---|
| 527 | }
|
|---|
| 528 | }
|
|---|
| 529 |
|
|---|
| 530 | return ((request_count << 16) | response_count);
|
|---|
| 531 | }
|
|---|
| 532 |
|
|---|
| 533 |
|
|---|
| 534 | // Process JTAG Sequence command and prepare response
|
|---|
| 535 | // request: pointer to request data
|
|---|
| 536 | // response: pointer to response data
|
|---|
| 537 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 538 | // number of bytes in request (upper 16 bits)
|
|---|
| 539 | static uint32_t DAP_JTAG_Sequence(const uint8_t *request, uint8_t *response) {
|
|---|
| 540 | uint32_t sequence_info;
|
|---|
| 541 | uint32_t sequence_count;
|
|---|
| 542 | uint32_t request_count;
|
|---|
| 543 | uint32_t response_count;
|
|---|
| 544 | uint32_t count;
|
|---|
| 545 |
|
|---|
| 546 | #if (DAP_JTAG != 0)
|
|---|
| 547 | *response++ = DAP_OK;
|
|---|
| 548 | #else
|
|---|
| 549 | *response++ = DAP_ERROR;
|
|---|
| 550 | #endif
|
|---|
| 551 | request_count = 1U;
|
|---|
| 552 | response_count = 1U;
|
|---|
| 553 |
|
|---|
| 554 | sequence_count = *request++;
|
|---|
| 555 | while (sequence_count--) {
|
|---|
| 556 | sequence_info = *request++;
|
|---|
| 557 | count = sequence_info & JTAG_SEQUENCE_TCK;
|
|---|
| 558 | if (count == 0U) {
|
|---|
| 559 | count = 64U;
|
|---|
| 560 | }
|
|---|
| 561 | count = (count + 7U) / 8U;
|
|---|
| 562 | #if (DAP_JTAG != 0)
|
|---|
| 563 | JTAG_Sequence(sequence_info, request, response);
|
|---|
| 564 | #endif
|
|---|
| 565 | request += count;
|
|---|
| 566 | request_count += count + 1U;
|
|---|
| 567 | #if (DAP_JTAG != 0)
|
|---|
| 568 | if ((sequence_info & JTAG_SEQUENCE_TDO) != 0U) {
|
|---|
| 569 | response += count;
|
|---|
| 570 | response_count += count;
|
|---|
| 571 | }
|
|---|
| 572 | #endif
|
|---|
| 573 | }
|
|---|
| 574 |
|
|---|
| 575 | return ((request_count << 16) | response_count);
|
|---|
| 576 | }
|
|---|
| 577 |
|
|---|
| 578 |
|
|---|
| 579 | // Process JTAG Configure command and prepare response
|
|---|
| 580 | // request: pointer to request data
|
|---|
| 581 | // response: pointer to response data
|
|---|
| 582 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 583 | // number of bytes in request (upper 16 bits)
|
|---|
| 584 | static uint32_t DAP_JTAG_Configure(const uint8_t *request, uint8_t *response) {
|
|---|
| 585 | uint32_t count;
|
|---|
| 586 | #if (DAP_JTAG != 0)
|
|---|
| 587 | uint32_t length;
|
|---|
| 588 | uint32_t bits;
|
|---|
| 589 | uint32_t n;
|
|---|
| 590 |
|
|---|
| 591 | count = *request++;
|
|---|
| 592 | DAP_Data.jtag_dev.count = (uint8_t)count;
|
|---|
| 593 |
|
|---|
| 594 | bits = 0U;
|
|---|
| 595 | for (n = 0U; n < count; n++) {
|
|---|
| 596 | length = *request++;
|
|---|
| 597 | DAP_Data.jtag_dev.ir_length[n] = (uint8_t)length;
|
|---|
| 598 | DAP_Data.jtag_dev.ir_before[n] = (uint16_t)bits;
|
|---|
| 599 | bits += length;
|
|---|
| 600 | }
|
|---|
| 601 | for (n = 0U; n < count; n++) {
|
|---|
| 602 | bits -= DAP_Data.jtag_dev.ir_length[n];
|
|---|
| 603 | DAP_Data.jtag_dev.ir_after[n] = (uint16_t)bits;
|
|---|
| 604 | }
|
|---|
| 605 |
|
|---|
| 606 | *response = DAP_OK;
|
|---|
| 607 | #else
|
|---|
| 608 | count = *request;
|
|---|
| 609 | *response = DAP_ERROR;
|
|---|
| 610 | #endif
|
|---|
| 611 |
|
|---|
| 612 | return (((count + 1U) << 16) | 1U);
|
|---|
| 613 | }
|
|---|
| 614 |
|
|---|
| 615 |
|
|---|
| 616 | // Process JTAG IDCODE command and prepare response
|
|---|
| 617 | // request: pointer to request data
|
|---|
| 618 | // response: pointer to response data
|
|---|
| 619 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 620 | // number of bytes in request (upper 16 bits)
|
|---|
| 621 | static uint32_t DAP_JTAG_IDCode(const uint8_t *request, uint8_t *response) {
|
|---|
| 622 | #if (DAP_JTAG != 0)
|
|---|
| 623 | uint32_t data;
|
|---|
| 624 |
|
|---|
| 625 | if (DAP_Data.debug_port != DAP_PORT_JTAG) {
|
|---|
| 626 | goto id_error;
|
|---|
| 627 | }
|
|---|
| 628 |
|
|---|
| 629 | // Device index (JTAP TAP)
|
|---|
| 630 | DAP_Data.jtag_dev.index = *request;
|
|---|
| 631 | if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
|
|---|
| 632 | goto id_error;
|
|---|
| 633 | }
|
|---|
| 634 |
|
|---|
| 635 | // Select JTAG chain
|
|---|
| 636 | JTAG_IR(JTAG_IDCODE);
|
|---|
| 637 |
|
|---|
| 638 | // Read IDCODE register
|
|---|
| 639 | data = JTAG_ReadIDCode();
|
|---|
| 640 |
|
|---|
| 641 | // Store Data
|
|---|
| 642 | *(response+0) = DAP_OK;
|
|---|
| 643 | *(response+1) = (uint8_t)(data >> 0);
|
|---|
| 644 | *(response+2) = (uint8_t)(data >> 8);
|
|---|
| 645 | *(response+3) = (uint8_t)(data >> 16);
|
|---|
| 646 | *(response+4) = (uint8_t)(data >> 24);
|
|---|
| 647 |
|
|---|
| 648 | return ((1U << 16) | 5U);
|
|---|
| 649 |
|
|---|
| 650 | id_error:
|
|---|
| 651 | #endif
|
|---|
| 652 | *response = DAP_ERROR;
|
|---|
| 653 | return ((1U << 16) | 1U);
|
|---|
| 654 | }
|
|---|
| 655 |
|
|---|
| 656 |
|
|---|
| 657 | // Process Transfer Configure command and prepare response
|
|---|
| 658 | // request: pointer to request data
|
|---|
| 659 | // response: pointer to response data
|
|---|
| 660 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 661 | // number of bytes in request (upper 16 bits)
|
|---|
| 662 | static uint32_t DAP_TransferConfigure(const uint8_t *request, uint8_t *response) {
|
|---|
| 663 |
|
|---|
| 664 | DAP_Data.transfer.idle_cycles = *(request+0);
|
|---|
| 665 | DAP_Data.transfer.retry_count = (uint16_t) *(request+1) |
|
|---|
| 666 | (uint16_t)(*(request+2) << 8);
|
|---|
| 667 | DAP_Data.transfer.match_retry = (uint16_t) *(request+3) |
|
|---|
| 668 | (uint16_t)(*(request+4) << 8);
|
|---|
| 669 |
|
|---|
| 670 | *response = DAP_OK;
|
|---|
| 671 | return ((5U << 16) | 1U);
|
|---|
| 672 | }
|
|---|
| 673 |
|
|---|
| 674 |
|
|---|
| 675 | // Process SWD Transfer command and prepare response
|
|---|
| 676 | // request: pointer to request data
|
|---|
| 677 | // response: pointer to response data
|
|---|
| 678 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 679 | // number of bytes in request (upper 16 bits)
|
|---|
| 680 | #if (DAP_SWD != 0)
|
|---|
| 681 | static uint32_t DAP_SWD_Transfer(const uint8_t *request, uint8_t *response) {
|
|---|
| 682 | const
|
|---|
| 683 | uint8_t *request_head;
|
|---|
| 684 | uint32_t request_count;
|
|---|
| 685 | uint32_t request_value;
|
|---|
| 686 | uint8_t *response_head;
|
|---|
| 687 | uint32_t response_count;
|
|---|
| 688 | uint32_t response_value;
|
|---|
| 689 | uint32_t post_read;
|
|---|
| 690 | uint32_t check_write;
|
|---|
| 691 | uint32_t match_value;
|
|---|
| 692 | uint32_t match_retry;
|
|---|
| 693 | uint32_t retry;
|
|---|
| 694 | uint32_t data;
|
|---|
| 695 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 696 | uint32_t timestamp;
|
|---|
| 697 | #endif
|
|---|
| 698 |
|
|---|
| 699 | request_head = request;
|
|---|
| 700 |
|
|---|
| 701 | response_count = 0U;
|
|---|
| 702 | response_value = 0U;
|
|---|
| 703 | response_head = response;
|
|---|
| 704 | response += 2;
|
|---|
| 705 |
|
|---|
| 706 | DAP_TransferAbort = 0U;
|
|---|
| 707 |
|
|---|
| 708 | post_read = 0U;
|
|---|
| 709 | check_write = 0U;
|
|---|
| 710 |
|
|---|
| 711 | request++; // Ignore DAP index
|
|---|
| 712 |
|
|---|
| 713 | request_count = *request++;
|
|---|
| 714 |
|
|---|
| 715 | for (; request_count != 0U; request_count--) {
|
|---|
| 716 | request_value = *request++;
|
|---|
| 717 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 718 | // Read register
|
|---|
| 719 | if (post_read) {
|
|---|
| 720 | // Read was posted before
|
|---|
| 721 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 722 | if ((request_value & (DAP_TRANSFER_APnDP | DAP_TRANSFER_MATCH_VALUE)) == DAP_TRANSFER_APnDP) {
|
|---|
| 723 | // Read previous AP data and post next AP read
|
|---|
| 724 | do {
|
|---|
| 725 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 726 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 727 | } else {
|
|---|
| 728 | // Read previous AP data
|
|---|
| 729 | do {
|
|---|
| 730 | response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 731 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 732 | post_read = 0U;
|
|---|
| 733 | }
|
|---|
| 734 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 735 | break;
|
|---|
| 736 | }
|
|---|
| 737 | // Store previous AP data
|
|---|
| 738 | *response++ = (uint8_t) data;
|
|---|
| 739 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 740 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 741 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 742 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 743 | if (post_read) {
|
|---|
| 744 | // Store Timestamp of next AP read
|
|---|
| 745 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 746 | timestamp = DAP_Data.timestamp;
|
|---|
| 747 | *response++ = (uint8_t) timestamp;
|
|---|
| 748 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 749 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 750 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 751 | }
|
|---|
| 752 | }
|
|---|
| 753 | #endif
|
|---|
| 754 | }
|
|---|
| 755 | if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
|
|---|
| 756 | // Read with value match
|
|---|
| 757 | match_value = (uint32_t)(*(request+0) << 0) |
|
|---|
| 758 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 759 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 760 | (uint32_t)(*(request+3) << 24);
|
|---|
| 761 | request += 4;
|
|---|
| 762 | match_retry = DAP_Data.transfer.match_retry;
|
|---|
| 763 | if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
|
|---|
| 764 | // Post AP read
|
|---|
| 765 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 766 | do {
|
|---|
| 767 | response_value = SWD_Transfer(request_value, NULL);
|
|---|
| 768 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 769 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 770 | break;
|
|---|
| 771 | }
|
|---|
| 772 | }
|
|---|
| 773 | do {
|
|---|
| 774 | // Read register until its value matches or retry counter expires
|
|---|
| 775 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 776 | do {
|
|---|
| 777 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 778 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 779 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 780 | break;
|
|---|
| 781 | }
|
|---|
| 782 | } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
|
|---|
| 783 | if ((data & DAP_Data.transfer.match_mask) != match_value) {
|
|---|
| 784 | response_value |= DAP_TRANSFER_MISMATCH;
|
|---|
| 785 | }
|
|---|
| 786 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 787 | break;
|
|---|
| 788 | }
|
|---|
| 789 | } else {
|
|---|
| 790 | // Normal read
|
|---|
| 791 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 792 | if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
|
|---|
| 793 | // Read AP register
|
|---|
| 794 | if (post_read == 0U) {
|
|---|
| 795 | // Post AP read
|
|---|
| 796 | do {
|
|---|
| 797 | response_value = SWD_Transfer(request_value, NULL);
|
|---|
| 798 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 799 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 800 | break;
|
|---|
| 801 | }
|
|---|
| 802 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 803 | // Store Timestamp
|
|---|
| 804 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 805 | timestamp = DAP_Data.timestamp;
|
|---|
| 806 | *response++ = (uint8_t) timestamp;
|
|---|
| 807 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 808 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 809 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 810 | }
|
|---|
| 811 | #endif
|
|---|
| 812 | post_read = 1U;
|
|---|
| 813 | }
|
|---|
| 814 | } else {
|
|---|
| 815 | // Read DP register
|
|---|
| 816 | do {
|
|---|
| 817 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 818 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 819 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 820 | break;
|
|---|
| 821 | }
|
|---|
| 822 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 823 | // Store Timestamp
|
|---|
| 824 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 825 | timestamp = DAP_Data.timestamp;
|
|---|
| 826 | *response++ = (uint8_t) timestamp;
|
|---|
| 827 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 828 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 829 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 830 | }
|
|---|
| 831 | #endif
|
|---|
| 832 | // Store data
|
|---|
| 833 | *response++ = (uint8_t) data;
|
|---|
| 834 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 835 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 836 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 837 | }
|
|---|
| 838 | }
|
|---|
| 839 | check_write = 0U;
|
|---|
| 840 | } else {
|
|---|
| 841 | // Write register
|
|---|
| 842 | if (post_read) {
|
|---|
| 843 | // Read previous data
|
|---|
| 844 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 845 | do {
|
|---|
| 846 | response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 847 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 848 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 849 | break;
|
|---|
| 850 | }
|
|---|
| 851 | // Store previous data
|
|---|
| 852 | *response++ = (uint8_t) data;
|
|---|
| 853 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 854 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 855 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 856 | post_read = 0U;
|
|---|
| 857 | }
|
|---|
| 858 | // Load data
|
|---|
| 859 | data = (uint32_t)(*(request+0) << 0) |
|
|---|
| 860 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 861 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 862 | (uint32_t)(*(request+3) << 24);
|
|---|
| 863 | request += 4;
|
|---|
| 864 | if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
|
|---|
| 865 | // Write match mask
|
|---|
| 866 | DAP_Data.transfer.match_mask = data;
|
|---|
| 867 | response_value = DAP_TRANSFER_OK;
|
|---|
| 868 | } else {
|
|---|
| 869 | // Write DP/AP register
|
|---|
| 870 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 871 | do {
|
|---|
| 872 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 873 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 874 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 875 | break;
|
|---|
| 876 | }
|
|---|
| 877 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 878 | // Store Timestamp
|
|---|
| 879 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 880 | timestamp = DAP_Data.timestamp;
|
|---|
| 881 | *response++ = (uint8_t) timestamp;
|
|---|
| 882 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 883 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 884 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 885 | }
|
|---|
| 886 | #endif
|
|---|
| 887 | check_write = 1U;
|
|---|
| 888 | }
|
|---|
| 889 | }
|
|---|
| 890 | response_count++;
|
|---|
| 891 | if (DAP_TransferAbort) {
|
|---|
| 892 | break;
|
|---|
| 893 | }
|
|---|
| 894 | }
|
|---|
| 895 |
|
|---|
| 896 | for (; request_count != 0U; request_count--) {
|
|---|
| 897 | // Process canceled requests
|
|---|
| 898 | request_value = *request++;
|
|---|
| 899 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 900 | // Read register
|
|---|
| 901 | if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
|
|---|
| 902 | // Read with value match
|
|---|
| 903 | request += 4;
|
|---|
| 904 | }
|
|---|
| 905 | } else {
|
|---|
| 906 | // Write register
|
|---|
| 907 | request += 4;
|
|---|
| 908 | }
|
|---|
| 909 | }
|
|---|
| 910 |
|
|---|
| 911 | if (response_value == DAP_TRANSFER_OK) {
|
|---|
| 912 | if (post_read) {
|
|---|
| 913 | // Read previous data
|
|---|
| 914 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 915 | do {
|
|---|
| 916 | response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 917 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 918 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 919 | goto end;
|
|---|
| 920 | }
|
|---|
| 921 | // Store previous data
|
|---|
| 922 | *response++ = (uint8_t) data;
|
|---|
| 923 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 924 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 925 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 926 | } else if (check_write) {
|
|---|
| 927 | // Check last write
|
|---|
| 928 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 929 | do {
|
|---|
| 930 | response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
|
|---|
| 931 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 932 | }
|
|---|
| 933 | }
|
|---|
| 934 |
|
|---|
| 935 | end:
|
|---|
| 936 | *(response_head+0) = (uint8_t)response_count;
|
|---|
| 937 | *(response_head+1) = (uint8_t)response_value;
|
|---|
| 938 |
|
|---|
| 939 | return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
|
|---|
| 940 | }
|
|---|
| 941 | #endif
|
|---|
| 942 |
|
|---|
| 943 |
|
|---|
| 944 | // Process JTAG Transfer command and prepare response
|
|---|
| 945 | // request: pointer to request data
|
|---|
| 946 | // response: pointer to response data
|
|---|
| 947 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 948 | // number of bytes in request (upper 16 bits)
|
|---|
| 949 | #if (DAP_JTAG != 0)
|
|---|
| 950 | static uint32_t DAP_JTAG_Transfer(const uint8_t *request, uint8_t *response) {
|
|---|
| 951 | const
|
|---|
| 952 | uint8_t *request_head;
|
|---|
| 953 | uint32_t request_count;
|
|---|
| 954 | uint32_t request_value;
|
|---|
| 955 | uint32_t request_ir;
|
|---|
| 956 | uint8_t *response_head;
|
|---|
| 957 | uint32_t response_count;
|
|---|
| 958 | uint32_t response_value;
|
|---|
| 959 | uint32_t post_read;
|
|---|
| 960 | uint32_t match_value;
|
|---|
| 961 | uint32_t match_retry;
|
|---|
| 962 | uint32_t retry;
|
|---|
| 963 | uint32_t data;
|
|---|
| 964 | uint32_t ir;
|
|---|
| 965 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 966 | uint32_t timestamp;
|
|---|
| 967 | #endif
|
|---|
| 968 |
|
|---|
| 969 | request_head = request;
|
|---|
| 970 |
|
|---|
| 971 | response_count = 0U;
|
|---|
| 972 | response_value = 0U;
|
|---|
| 973 | response_head = response;
|
|---|
| 974 | response += 2;
|
|---|
| 975 |
|
|---|
| 976 | DAP_TransferAbort = 0U;
|
|---|
| 977 |
|
|---|
| 978 | ir = 0U;
|
|---|
| 979 | post_read = 0U;
|
|---|
| 980 |
|
|---|
| 981 | // Device index (JTAP TAP)
|
|---|
| 982 | DAP_Data.jtag_dev.index = *request++;
|
|---|
| 983 | if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
|
|---|
| 984 | goto end;
|
|---|
| 985 | }
|
|---|
| 986 |
|
|---|
| 987 | request_count = *request++;
|
|---|
| 988 |
|
|---|
| 989 | for (; request_count != 0U; request_count--) {
|
|---|
| 990 | request_value = *request++;
|
|---|
| 991 | request_ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
|
|---|
| 992 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 993 | // Read register
|
|---|
| 994 | if (post_read) {
|
|---|
| 995 | // Read was posted before
|
|---|
| 996 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 997 | if ((ir == request_ir) && ((request_value & DAP_TRANSFER_MATCH_VALUE) == 0U)) {
|
|---|
| 998 | // Read previous data and post next read
|
|---|
| 999 | do {
|
|---|
| 1000 | response_value = JTAG_Transfer(request_value, &data);
|
|---|
| 1001 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1002 | } else {
|
|---|
| 1003 | // Select JTAG chain
|
|---|
| 1004 | if (ir != JTAG_DPACC) {
|
|---|
| 1005 | ir = JTAG_DPACC;
|
|---|
| 1006 | JTAG_IR(ir);
|
|---|
| 1007 | }
|
|---|
| 1008 | // Read previous data
|
|---|
| 1009 | do {
|
|---|
| 1010 | response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 1011 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1012 | post_read = 0U;
|
|---|
| 1013 | }
|
|---|
| 1014 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1015 | break;
|
|---|
| 1016 | }
|
|---|
| 1017 | // Store previous data
|
|---|
| 1018 | *response++ = (uint8_t) data;
|
|---|
| 1019 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 1020 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 1021 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 1022 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 1023 | if (post_read) {
|
|---|
| 1024 | // Store Timestamp of next AP read
|
|---|
| 1025 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 1026 | timestamp = DAP_Data.timestamp;
|
|---|
| 1027 | *response++ = (uint8_t) timestamp;
|
|---|
| 1028 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 1029 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 1030 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 1031 | }
|
|---|
| 1032 | }
|
|---|
| 1033 | #endif
|
|---|
| 1034 | }
|
|---|
| 1035 | if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
|
|---|
| 1036 | // Read with value match
|
|---|
| 1037 | match_value = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1038 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 1039 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 1040 | (uint32_t)(*(request+3) << 24);
|
|---|
| 1041 | request += 4;
|
|---|
| 1042 | match_retry = DAP_Data.transfer.match_retry;
|
|---|
| 1043 | // Select JTAG chain
|
|---|
| 1044 | if (ir != request_ir) {
|
|---|
| 1045 | ir = request_ir;
|
|---|
| 1046 | JTAG_IR(ir);
|
|---|
| 1047 | }
|
|---|
| 1048 | // Post DP/AP read
|
|---|
| 1049 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1050 | do {
|
|---|
| 1051 | response_value = JTAG_Transfer(request_value, NULL);
|
|---|
| 1052 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1053 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1054 | break;
|
|---|
| 1055 | }
|
|---|
| 1056 | do {
|
|---|
| 1057 | // Read register until its value matches or retry counter expires
|
|---|
| 1058 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1059 | do {
|
|---|
| 1060 | response_value = JTAG_Transfer(request_value, &data);
|
|---|
| 1061 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1062 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1063 | break;
|
|---|
| 1064 | }
|
|---|
| 1065 | } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
|
|---|
| 1066 | if ((data & DAP_Data.transfer.match_mask) != match_value) {
|
|---|
| 1067 | response_value |= DAP_TRANSFER_MISMATCH;
|
|---|
| 1068 | }
|
|---|
| 1069 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1070 | break;
|
|---|
| 1071 | }
|
|---|
| 1072 | } else {
|
|---|
| 1073 | // Normal read
|
|---|
| 1074 | if (post_read == 0U) {
|
|---|
| 1075 | // Select JTAG chain
|
|---|
| 1076 | if (ir != request_ir) {
|
|---|
| 1077 | ir = request_ir;
|
|---|
| 1078 | JTAG_IR(ir);
|
|---|
| 1079 | }
|
|---|
| 1080 | // Post DP/AP read
|
|---|
| 1081 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1082 | do {
|
|---|
| 1083 | response_value = JTAG_Transfer(request_value, NULL);
|
|---|
| 1084 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1085 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1086 | break;
|
|---|
| 1087 | }
|
|---|
| 1088 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 1089 | // Store Timestamp
|
|---|
| 1090 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 1091 | timestamp = DAP_Data.timestamp;
|
|---|
| 1092 | *response++ = (uint8_t) timestamp;
|
|---|
| 1093 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 1094 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 1095 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 1096 | }
|
|---|
| 1097 | #endif
|
|---|
| 1098 | post_read = 1U;
|
|---|
| 1099 | }
|
|---|
| 1100 | }
|
|---|
| 1101 | } else {
|
|---|
| 1102 | // Write register
|
|---|
| 1103 | if (post_read) {
|
|---|
| 1104 | // Select JTAG chain
|
|---|
| 1105 | if (ir != JTAG_DPACC) {
|
|---|
| 1106 | ir = JTAG_DPACC;
|
|---|
| 1107 | JTAG_IR(ir);
|
|---|
| 1108 | }
|
|---|
| 1109 | // Read previous data
|
|---|
| 1110 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1111 | do {
|
|---|
| 1112 | response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 1113 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1114 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1115 | break;
|
|---|
| 1116 | }
|
|---|
| 1117 | // Store previous data
|
|---|
| 1118 | *response++ = (uint8_t) data;
|
|---|
| 1119 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 1120 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 1121 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 1122 | post_read = 0U;
|
|---|
| 1123 | }
|
|---|
| 1124 | // Load data
|
|---|
| 1125 | data = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1126 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 1127 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 1128 | (uint32_t)(*(request+3) << 24);
|
|---|
| 1129 | request += 4;
|
|---|
| 1130 | if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
|
|---|
| 1131 | // Write match mask
|
|---|
| 1132 | DAP_Data.transfer.match_mask = data;
|
|---|
| 1133 | response_value = DAP_TRANSFER_OK;
|
|---|
| 1134 | } else {
|
|---|
| 1135 | // Select JTAG chain
|
|---|
| 1136 | if (ir != request_ir) {
|
|---|
| 1137 | ir = request_ir;
|
|---|
| 1138 | JTAG_IR(ir);
|
|---|
| 1139 | }
|
|---|
| 1140 | // Write DP/AP register
|
|---|
| 1141 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1142 | do {
|
|---|
| 1143 | response_value = JTAG_Transfer(request_value, &data);
|
|---|
| 1144 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1145 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1146 | break;
|
|---|
| 1147 | }
|
|---|
| 1148 | #if (TIMESTAMP_CLOCK != 0U)
|
|---|
| 1149 | // Store Timestamp
|
|---|
| 1150 | if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
|
|---|
| 1151 | timestamp = DAP_Data.timestamp;
|
|---|
| 1152 | *response++ = (uint8_t) timestamp;
|
|---|
| 1153 | *response++ = (uint8_t)(timestamp >> 8);
|
|---|
| 1154 | *response++ = (uint8_t)(timestamp >> 16);
|
|---|
| 1155 | *response++ = (uint8_t)(timestamp >> 24);
|
|---|
| 1156 | }
|
|---|
| 1157 | #endif
|
|---|
| 1158 | }
|
|---|
| 1159 | }
|
|---|
| 1160 | response_count++;
|
|---|
| 1161 | if (DAP_TransferAbort) {
|
|---|
| 1162 | break;
|
|---|
| 1163 | }
|
|---|
| 1164 | }
|
|---|
| 1165 |
|
|---|
| 1166 | for (; request_count != 0U; request_count--) {
|
|---|
| 1167 | // Process canceled requests
|
|---|
| 1168 | request_value = *request++;
|
|---|
| 1169 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 1170 | // Read register
|
|---|
| 1171 | if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
|
|---|
| 1172 | // Read with value match
|
|---|
| 1173 | request += 4;
|
|---|
| 1174 | }
|
|---|
| 1175 | } else {
|
|---|
| 1176 | // Write register
|
|---|
| 1177 | request += 4;
|
|---|
| 1178 | }
|
|---|
| 1179 | }
|
|---|
| 1180 |
|
|---|
| 1181 | if (response_value == DAP_TRANSFER_OK) {
|
|---|
| 1182 | // Select JTAG chain
|
|---|
| 1183 | if (ir != JTAG_DPACC) {
|
|---|
| 1184 | ir = JTAG_DPACC;
|
|---|
| 1185 | JTAG_IR(ir);
|
|---|
| 1186 | }
|
|---|
| 1187 | if (post_read) {
|
|---|
| 1188 | // Read previous data
|
|---|
| 1189 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1190 | do {
|
|---|
| 1191 | response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
|
|---|
| 1192 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1193 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1194 | goto end;
|
|---|
| 1195 | }
|
|---|
| 1196 | // Store previous data
|
|---|
| 1197 | *response++ = (uint8_t) data;
|
|---|
| 1198 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 1199 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 1200 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 1201 | } else {
|
|---|
| 1202 | // Check last write
|
|---|
| 1203 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1204 | do {
|
|---|
| 1205 | response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
|
|---|
| 1206 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1207 | }
|
|---|
| 1208 | }
|
|---|
| 1209 |
|
|---|
| 1210 | end:
|
|---|
| 1211 | *(response_head+0) = (uint8_t)response_count;
|
|---|
| 1212 | *(response_head+1) = (uint8_t)response_value;
|
|---|
| 1213 |
|
|---|
| 1214 | return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
|
|---|
| 1215 | }
|
|---|
| 1216 | #endif
|
|---|
| 1217 |
|
|---|
| 1218 |
|
|---|
| 1219 | // Process Dummy Transfer command and prepare response
|
|---|
| 1220 | // request: pointer to request data
|
|---|
| 1221 | // response: pointer to response data
|
|---|
| 1222 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1223 | // number of bytes in request (upper 16 bits)
|
|---|
| 1224 | static uint32_t DAP_Dummy_Transfer(const uint8_t *request, uint8_t *response) {
|
|---|
| 1225 | const
|
|---|
| 1226 | uint8_t *request_head;
|
|---|
| 1227 | uint32_t request_count;
|
|---|
| 1228 | uint32_t request_value;
|
|---|
| 1229 |
|
|---|
| 1230 | request_head = request;
|
|---|
| 1231 |
|
|---|
| 1232 | request++; // Ignore DAP index
|
|---|
| 1233 |
|
|---|
| 1234 | request_count = *request++;
|
|---|
| 1235 |
|
|---|
| 1236 | for (; request_count != 0U; request_count--) {
|
|---|
| 1237 | // Process dummy requests
|
|---|
| 1238 | request_value = *request++;
|
|---|
| 1239 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 1240 | // Read register
|
|---|
| 1241 | if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
|
|---|
| 1242 | // Read with value match
|
|---|
| 1243 | request += 4;
|
|---|
| 1244 | }
|
|---|
| 1245 | } else {
|
|---|
| 1246 | // Write register
|
|---|
| 1247 | request += 4;
|
|---|
| 1248 | }
|
|---|
| 1249 | }
|
|---|
| 1250 |
|
|---|
| 1251 | *(response+0) = 0U; // Response count
|
|---|
| 1252 | *(response+1) = 0U; // Response value
|
|---|
| 1253 |
|
|---|
| 1254 | return (((uint32_t)(request - request_head) << 16) | 2U);
|
|---|
| 1255 | }
|
|---|
| 1256 |
|
|---|
| 1257 |
|
|---|
| 1258 | // Process Transfer command and prepare response
|
|---|
| 1259 | // request: pointer to request data
|
|---|
| 1260 | // response: pointer to response data
|
|---|
| 1261 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1262 | // number of bytes in request (upper 16 bits)
|
|---|
| 1263 | static uint32_t DAP_Transfer(const uint8_t *request, uint8_t *response) {
|
|---|
| 1264 | uint32_t num;
|
|---|
| 1265 |
|
|---|
| 1266 | switch (DAP_Data.debug_port) {
|
|---|
| 1267 | #if (DAP_SWD != 0)
|
|---|
| 1268 | case DAP_PORT_SWD:
|
|---|
| 1269 | num = DAP_SWD_Transfer(request, response);
|
|---|
| 1270 | break;
|
|---|
| 1271 | #endif
|
|---|
| 1272 | #if (DAP_JTAG != 0)
|
|---|
| 1273 | case DAP_PORT_JTAG:
|
|---|
| 1274 | num = DAP_JTAG_Transfer(request, response);
|
|---|
| 1275 | break;
|
|---|
| 1276 | #endif
|
|---|
| 1277 | default:
|
|---|
| 1278 | num = DAP_Dummy_Transfer(request, response);
|
|---|
| 1279 | break;
|
|---|
| 1280 | }
|
|---|
| 1281 |
|
|---|
| 1282 | return (num);
|
|---|
| 1283 | }
|
|---|
| 1284 |
|
|---|
| 1285 |
|
|---|
| 1286 | // Process SWD Transfer Block command and prepare response
|
|---|
| 1287 | // request: pointer to request data
|
|---|
| 1288 | // response: pointer to response data
|
|---|
| 1289 | // return: number of bytes in response
|
|---|
| 1290 | #if (DAP_SWD != 0)
|
|---|
| 1291 | static uint32_t DAP_SWD_TransferBlock(const uint8_t *request, uint8_t *response) {
|
|---|
| 1292 | uint32_t request_count;
|
|---|
| 1293 | uint32_t request_value;
|
|---|
| 1294 | uint32_t response_count;
|
|---|
| 1295 | uint32_t response_value;
|
|---|
| 1296 | uint8_t *response_head;
|
|---|
| 1297 | uint32_t retry;
|
|---|
| 1298 | uint32_t data;
|
|---|
| 1299 |
|
|---|
| 1300 | response_count = 0U;
|
|---|
| 1301 | response_value = 0U;
|
|---|
| 1302 | response_head = response;
|
|---|
| 1303 | response += 3;
|
|---|
| 1304 |
|
|---|
| 1305 | DAP_TransferAbort = 0U;
|
|---|
| 1306 |
|
|---|
| 1307 | request++; // Ignore DAP index
|
|---|
| 1308 |
|
|---|
| 1309 | request_count = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1310 | (uint32_t)(*(request+1) << 8);
|
|---|
| 1311 | request += 2;
|
|---|
| 1312 | if (request_count == 0U) {
|
|---|
| 1313 | goto end;
|
|---|
| 1314 | }
|
|---|
| 1315 |
|
|---|
| 1316 | request_value = *request++;
|
|---|
| 1317 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 1318 | // Read register block
|
|---|
| 1319 | if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
|
|---|
| 1320 | // Post AP read
|
|---|
| 1321 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1322 | do {
|
|---|
| 1323 | response_value = SWD_Transfer(request_value, NULL);
|
|---|
| 1324 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1325 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1326 | goto end;
|
|---|
| 1327 | }
|
|---|
| 1328 | }
|
|---|
| 1329 | while (request_count--) {
|
|---|
| 1330 | // Read DP/AP register
|
|---|
| 1331 | if ((request_count == 0U) && ((request_value & DAP_TRANSFER_APnDP) != 0U)) {
|
|---|
| 1332 | // Last AP read
|
|---|
| 1333 | request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
|
|---|
| 1334 | }
|
|---|
| 1335 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1336 | do {
|
|---|
| 1337 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 1338 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1339 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1340 | goto end;
|
|---|
| 1341 | }
|
|---|
| 1342 | // Store data
|
|---|
| 1343 | *response++ = (uint8_t) data;
|
|---|
| 1344 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 1345 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 1346 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 1347 | response_count++;
|
|---|
| 1348 | }
|
|---|
| 1349 | } else {
|
|---|
| 1350 | // Write register block
|
|---|
| 1351 | while (request_count--) {
|
|---|
| 1352 | // Load data
|
|---|
| 1353 | data = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1354 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 1355 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 1356 | (uint32_t)(*(request+3) << 24);
|
|---|
| 1357 | request += 4;
|
|---|
| 1358 | // Write DP/AP register
|
|---|
| 1359 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1360 | do {
|
|---|
| 1361 | response_value = SWD_Transfer(request_value, &data);
|
|---|
| 1362 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1363 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1364 | goto end;
|
|---|
| 1365 | }
|
|---|
| 1366 | response_count++;
|
|---|
| 1367 | }
|
|---|
| 1368 | // Check last write
|
|---|
| 1369 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1370 | do {
|
|---|
| 1371 | response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
|
|---|
| 1372 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1373 | }
|
|---|
| 1374 |
|
|---|
| 1375 | end:
|
|---|
| 1376 | *(response_head+0) = (uint8_t)(response_count >> 0);
|
|---|
| 1377 | *(response_head+1) = (uint8_t)(response_count >> 8);
|
|---|
| 1378 | *(response_head+2) = (uint8_t) response_value;
|
|---|
| 1379 |
|
|---|
| 1380 | return ((uint32_t)(response - response_head));
|
|---|
| 1381 | }
|
|---|
| 1382 | #endif
|
|---|
| 1383 |
|
|---|
| 1384 |
|
|---|
| 1385 | // Process JTAG Transfer Block command and prepare response
|
|---|
| 1386 | // request: pointer to request data
|
|---|
| 1387 | // response: pointer to response data
|
|---|
| 1388 | // return: number of bytes in response
|
|---|
| 1389 | #if (DAP_JTAG != 0)
|
|---|
| 1390 | static uint32_t DAP_JTAG_TransferBlock(const uint8_t *request, uint8_t *response) {
|
|---|
| 1391 | uint32_t request_count;
|
|---|
| 1392 | uint32_t request_value;
|
|---|
| 1393 | uint32_t response_count;
|
|---|
| 1394 | uint32_t response_value;
|
|---|
| 1395 | uint8_t *response_head;
|
|---|
| 1396 | uint32_t retry;
|
|---|
| 1397 | uint32_t data;
|
|---|
| 1398 | uint32_t ir;
|
|---|
| 1399 |
|
|---|
| 1400 | response_count = 0U;
|
|---|
| 1401 | response_value = 0U;
|
|---|
| 1402 | response_head = response;
|
|---|
| 1403 | response += 3;
|
|---|
| 1404 |
|
|---|
| 1405 | DAP_TransferAbort = 0U;
|
|---|
| 1406 |
|
|---|
| 1407 | // Device index (JTAP TAP)
|
|---|
| 1408 | DAP_Data.jtag_dev.index = *request++;
|
|---|
| 1409 | if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
|
|---|
| 1410 | goto end;
|
|---|
| 1411 | }
|
|---|
| 1412 |
|
|---|
| 1413 | request_count = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1414 | (uint32_t)(*(request+1) << 8);
|
|---|
| 1415 | request += 2;
|
|---|
| 1416 | if (request_count == 0U) {
|
|---|
| 1417 | goto end;
|
|---|
| 1418 | }
|
|---|
| 1419 |
|
|---|
| 1420 | request_value = *request++;
|
|---|
| 1421 |
|
|---|
| 1422 | // Select JTAG chain
|
|---|
| 1423 | ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
|
|---|
| 1424 | JTAG_IR(ir);
|
|---|
| 1425 |
|
|---|
| 1426 | if ((request_value & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 1427 | // Post read
|
|---|
| 1428 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1429 | do {
|
|---|
| 1430 | response_value = JTAG_Transfer(request_value, NULL);
|
|---|
| 1431 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1432 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1433 | goto end;
|
|---|
| 1434 | }
|
|---|
| 1435 | // Read register block
|
|---|
| 1436 | while (request_count--) {
|
|---|
| 1437 | // Read DP/AP register
|
|---|
| 1438 | if (request_count == 0U) {
|
|---|
| 1439 | // Last read
|
|---|
| 1440 | if (ir != JTAG_DPACC) {
|
|---|
| 1441 | JTAG_IR(JTAG_DPACC);
|
|---|
| 1442 | }
|
|---|
| 1443 | request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
|
|---|
| 1444 | }
|
|---|
| 1445 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1446 | do {
|
|---|
| 1447 | response_value = JTAG_Transfer(request_value, &data);
|
|---|
| 1448 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1449 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1450 | goto end;
|
|---|
| 1451 | }
|
|---|
| 1452 | // Store data
|
|---|
| 1453 | *response++ = (uint8_t) data;
|
|---|
| 1454 | *response++ = (uint8_t)(data >> 8);
|
|---|
| 1455 | *response++ = (uint8_t)(data >> 16);
|
|---|
| 1456 | *response++ = (uint8_t)(data >> 24);
|
|---|
| 1457 | response_count++;
|
|---|
| 1458 | }
|
|---|
| 1459 | } else {
|
|---|
| 1460 | // Write register block
|
|---|
| 1461 | while (request_count--) {
|
|---|
| 1462 | // Load data
|
|---|
| 1463 | data = (uint32_t)(*(request+0) << 0) |
|
|---|
| 1464 | (uint32_t)(*(request+1) << 8) |
|
|---|
| 1465 | (uint32_t)(*(request+2) << 16) |
|
|---|
| 1466 | (uint32_t)(*(request+3) << 24);
|
|---|
| 1467 | request += 4;
|
|---|
| 1468 | // Write DP/AP register
|
|---|
| 1469 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1470 | do {
|
|---|
| 1471 | response_value = JTAG_Transfer(request_value, &data);
|
|---|
| 1472 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1473 | if (response_value != DAP_TRANSFER_OK) {
|
|---|
| 1474 | goto end;
|
|---|
| 1475 | }
|
|---|
| 1476 | response_count++;
|
|---|
| 1477 | }
|
|---|
| 1478 | // Check last write
|
|---|
| 1479 | if (ir != JTAG_DPACC) {
|
|---|
| 1480 | JTAG_IR(JTAG_DPACC);
|
|---|
| 1481 | }
|
|---|
| 1482 | retry = DAP_Data.transfer.retry_count;
|
|---|
| 1483 | do {
|
|---|
| 1484 | response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
|
|---|
| 1485 | } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
|
|---|
| 1486 | }
|
|---|
| 1487 |
|
|---|
| 1488 | end:
|
|---|
| 1489 | *(response_head+0) = (uint8_t)(response_count >> 0);
|
|---|
| 1490 | *(response_head+1) = (uint8_t)(response_count >> 8);
|
|---|
| 1491 | *(response_head+2) = (uint8_t) response_value;
|
|---|
| 1492 |
|
|---|
| 1493 | return ((uint32_t)(response - response_head));
|
|---|
| 1494 | }
|
|---|
| 1495 | #endif
|
|---|
| 1496 |
|
|---|
| 1497 |
|
|---|
| 1498 | // Process Transfer Block command and prepare response
|
|---|
| 1499 | // request: pointer to request data
|
|---|
| 1500 | // response: pointer to response data
|
|---|
| 1501 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1502 | // number of bytes in request (upper 16 bits)
|
|---|
| 1503 | static uint32_t DAP_TransferBlock(const uint8_t *request, uint8_t *response) {
|
|---|
| 1504 | uint32_t num;
|
|---|
| 1505 |
|
|---|
| 1506 | switch (DAP_Data.debug_port) {
|
|---|
| 1507 | #if (DAP_SWD != 0)
|
|---|
| 1508 | case DAP_PORT_SWD:
|
|---|
| 1509 | num = DAP_SWD_TransferBlock (request, response);
|
|---|
| 1510 | break;
|
|---|
| 1511 | #endif
|
|---|
| 1512 | #if (DAP_JTAG != 0)
|
|---|
| 1513 | case DAP_PORT_JTAG:
|
|---|
| 1514 | num = DAP_JTAG_TransferBlock(request, response);
|
|---|
| 1515 | break;
|
|---|
| 1516 | #endif
|
|---|
| 1517 | default:
|
|---|
| 1518 | *(response+0) = 0U; // Response count [7:0]
|
|---|
| 1519 | *(response+1) = 0U; // Response count[15:8]
|
|---|
| 1520 | *(response+2) = 0U; // Response value
|
|---|
| 1521 | num = 3U;
|
|---|
| 1522 | break;
|
|---|
| 1523 | }
|
|---|
| 1524 |
|
|---|
| 1525 | if ((*(request+3) & DAP_TRANSFER_RnW) != 0U) {
|
|---|
| 1526 | // Read register block
|
|---|
| 1527 | num |= 4U << 16;
|
|---|
| 1528 | } else {
|
|---|
| 1529 | // Write register block
|
|---|
| 1530 | num |= (4U + (((uint32_t)(*(request+1)) | (uint32_t)(*(request+2) << 8)) * 4)) << 16;
|
|---|
| 1531 | }
|
|---|
| 1532 |
|
|---|
| 1533 | return (num);
|
|---|
| 1534 | }
|
|---|
| 1535 |
|
|---|
| 1536 |
|
|---|
| 1537 | // Process SWD Write ABORT command and prepare response
|
|---|
| 1538 | // request: pointer to request data
|
|---|
| 1539 | // response: pointer to response data
|
|---|
| 1540 | // return: number of bytes in response
|
|---|
| 1541 | #if (DAP_SWD != 0)
|
|---|
| 1542 | static uint32_t DAP_SWD_WriteAbort(const uint8_t *request, uint8_t *response) {
|
|---|
| 1543 | uint32_t data;
|
|---|
| 1544 |
|
|---|
| 1545 | // Load data (Ignore DAP index)
|
|---|
| 1546 | data = (uint32_t)(*(request+1) << 0) |
|
|---|
| 1547 | (uint32_t)(*(request+2) << 8) |
|
|---|
| 1548 | (uint32_t)(*(request+3) << 16) |
|
|---|
| 1549 | (uint32_t)(*(request+4) << 24);
|
|---|
| 1550 |
|
|---|
| 1551 | // Write Abort register
|
|---|
| 1552 | SWD_Transfer(DP_ABORT, &data);
|
|---|
| 1553 |
|
|---|
| 1554 | *response = DAP_OK;
|
|---|
| 1555 | return (1U);
|
|---|
| 1556 | }
|
|---|
| 1557 | #endif
|
|---|
| 1558 |
|
|---|
| 1559 |
|
|---|
| 1560 | // Process JTAG Write ABORT command and prepare response
|
|---|
| 1561 | // request: pointer to request data
|
|---|
| 1562 | // response: pointer to response data
|
|---|
| 1563 | // return: number of bytes in response
|
|---|
| 1564 | #if (DAP_JTAG != 0)
|
|---|
| 1565 | static uint32_t DAP_JTAG_WriteAbort(const uint8_t *request, uint8_t *response) {
|
|---|
| 1566 | uint32_t data;
|
|---|
| 1567 |
|
|---|
| 1568 | // Device index (JTAP TAP)
|
|---|
| 1569 | DAP_Data.jtag_dev.index = *request;
|
|---|
| 1570 | if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
|
|---|
| 1571 | *response = DAP_ERROR;
|
|---|
| 1572 | return (1U);
|
|---|
| 1573 | }
|
|---|
| 1574 |
|
|---|
| 1575 | // Select JTAG chain
|
|---|
| 1576 | JTAG_IR(JTAG_ABORT);
|
|---|
| 1577 |
|
|---|
| 1578 | // Load data
|
|---|
| 1579 | data = (uint32_t)(*(request+1) << 0) |
|
|---|
| 1580 | (uint32_t)(*(request+2) << 8) |
|
|---|
| 1581 | (uint32_t)(*(request+3) << 16) |
|
|---|
| 1582 | (uint32_t)(*(request+4) << 24);
|
|---|
| 1583 |
|
|---|
| 1584 | // Write Abort register
|
|---|
| 1585 | JTAG_WriteAbort(data);
|
|---|
| 1586 |
|
|---|
| 1587 | *response = DAP_OK;
|
|---|
| 1588 | return (1U);
|
|---|
| 1589 | }
|
|---|
| 1590 | #endif
|
|---|
| 1591 |
|
|---|
| 1592 |
|
|---|
| 1593 | // Process Write ABORT command and prepare response
|
|---|
| 1594 | // request: pointer to request data
|
|---|
| 1595 | // response: pointer to response data
|
|---|
| 1596 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1597 | // number of bytes in request (upper 16 bits)
|
|---|
| 1598 | static uint32_t DAP_WriteAbort(const uint8_t *request, uint8_t *response) {
|
|---|
| 1599 | uint32_t num;
|
|---|
| 1600 |
|
|---|
| 1601 | switch (DAP_Data.debug_port) {
|
|---|
| 1602 | #if (DAP_SWD != 0)
|
|---|
| 1603 | case DAP_PORT_SWD:
|
|---|
| 1604 | num = DAP_SWD_WriteAbort (request, response);
|
|---|
| 1605 | break;
|
|---|
| 1606 | #endif
|
|---|
| 1607 | #if (DAP_JTAG != 0)
|
|---|
| 1608 | case DAP_PORT_JTAG:
|
|---|
| 1609 | num = DAP_JTAG_WriteAbort(request, response);
|
|---|
| 1610 | break;
|
|---|
| 1611 | #endif
|
|---|
| 1612 | default:
|
|---|
| 1613 | *response = DAP_ERROR;
|
|---|
| 1614 | num = 1U;
|
|---|
| 1615 | break;
|
|---|
| 1616 | }
|
|---|
| 1617 | return ((5U << 16) | num);
|
|---|
| 1618 | }
|
|---|
| 1619 |
|
|---|
| 1620 |
|
|---|
| 1621 | // Process DAP Vendor command request and prepare response
|
|---|
| 1622 | // Default function (can be overridden)
|
|---|
| 1623 | // request: pointer to request data
|
|---|
| 1624 | // response: pointer to response data
|
|---|
| 1625 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1626 | // number of bytes in request (upper 16 bits)
|
|---|
| 1627 | __WEAK uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
|
|---|
| 1628 | (void)request;
|
|---|
| 1629 | *response = ID_DAP_Invalid;
|
|---|
| 1630 | return ((1U << 16) | 1U);
|
|---|
| 1631 | }
|
|---|
| 1632 |
|
|---|
| 1633 |
|
|---|
| 1634 | // Process DAP command request and prepare response
|
|---|
| 1635 | // request: pointer to request data
|
|---|
| 1636 | // response: pointer to response data
|
|---|
| 1637 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1638 | // number of bytes in request (upper 16 bits)
|
|---|
| 1639 | uint32_t DAP_ProcessCommand(const uint8_t *request, uint8_t *response) {
|
|---|
| 1640 | uint32_t num;
|
|---|
| 1641 |
|
|---|
| 1642 | if ((*request >= ID_DAP_Vendor0) && (*request <= ID_DAP_Vendor31)) {
|
|---|
| 1643 | return DAP_ProcessVendorCommand(request, response);
|
|---|
| 1644 | }
|
|---|
| 1645 |
|
|---|
| 1646 | *response++ = *request;
|
|---|
| 1647 |
|
|---|
| 1648 | switch (*request++) {
|
|---|
| 1649 | case ID_DAP_Info:
|
|---|
| 1650 | num = DAP_Info(*request, response+1);
|
|---|
| 1651 | *response = (uint8_t)num;
|
|---|
| 1652 | return ((2U << 16) + 2U + num);
|
|---|
| 1653 |
|
|---|
| 1654 | case ID_DAP_HostStatus:
|
|---|
| 1655 | num = DAP_HostStatus(request, response);
|
|---|
| 1656 | break;
|
|---|
| 1657 |
|
|---|
| 1658 | case ID_DAP_Connect:
|
|---|
| 1659 | num = DAP_Connect(request, response);
|
|---|
| 1660 | break;
|
|---|
| 1661 | case ID_DAP_Disconnect:
|
|---|
| 1662 | num = DAP_Disconnect(response);
|
|---|
| 1663 | break;
|
|---|
| 1664 |
|
|---|
| 1665 | case ID_DAP_Delay:
|
|---|
| 1666 | num = DAP_Delay(request, response);
|
|---|
| 1667 | break;
|
|---|
| 1668 |
|
|---|
| 1669 | case ID_DAP_ResetTarget:
|
|---|
| 1670 | num = DAP_ResetTarget(response);
|
|---|
| 1671 | break;
|
|---|
| 1672 |
|
|---|
| 1673 | case ID_DAP_SWJ_Pins:
|
|---|
| 1674 | num = DAP_SWJ_Pins(request, response);
|
|---|
| 1675 | break;
|
|---|
| 1676 | case ID_DAP_SWJ_Clock:
|
|---|
| 1677 | num = DAP_SWJ_Clock(request, response);
|
|---|
| 1678 | break;
|
|---|
| 1679 | case ID_DAP_SWJ_Sequence:
|
|---|
| 1680 | num = DAP_SWJ_Sequence(request, response);
|
|---|
| 1681 | break;
|
|---|
| 1682 |
|
|---|
| 1683 | case ID_DAP_SWD_Configure:
|
|---|
| 1684 | num = DAP_SWD_Configure(request, response);
|
|---|
| 1685 | break;
|
|---|
| 1686 | case ID_DAP_SWD_Sequence:
|
|---|
| 1687 | num = DAP_SWD_Sequence(request, response);
|
|---|
| 1688 | break;
|
|---|
| 1689 |
|
|---|
| 1690 | case ID_DAP_JTAG_Sequence:
|
|---|
| 1691 | num = DAP_JTAG_Sequence(request, response);
|
|---|
| 1692 | break;
|
|---|
| 1693 | case ID_DAP_JTAG_Configure:
|
|---|
| 1694 | num = DAP_JTAG_Configure(request, response);
|
|---|
| 1695 | break;
|
|---|
| 1696 | case ID_DAP_JTAG_IDCODE:
|
|---|
| 1697 | num = DAP_JTAG_IDCode(request, response);
|
|---|
| 1698 | break;
|
|---|
| 1699 |
|
|---|
| 1700 | case ID_DAP_TransferConfigure:
|
|---|
| 1701 | num = DAP_TransferConfigure(request, response);
|
|---|
| 1702 | break;
|
|---|
| 1703 | case ID_DAP_Transfer:
|
|---|
| 1704 | num = DAP_Transfer(request, response);
|
|---|
| 1705 | break;
|
|---|
| 1706 | case ID_DAP_TransferBlock:
|
|---|
| 1707 | num = DAP_TransferBlock(request, response);
|
|---|
| 1708 | break;
|
|---|
| 1709 |
|
|---|
| 1710 | case ID_DAP_WriteABORT:
|
|---|
| 1711 | num = DAP_WriteAbort(request, response);
|
|---|
| 1712 | break;
|
|---|
| 1713 |
|
|---|
| 1714 | #if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
|---|
| 1715 | case ID_DAP_SWO_Transport:
|
|---|
| 1716 | num = SWO_Transport(request, response);
|
|---|
| 1717 | break;
|
|---|
| 1718 | case ID_DAP_SWO_Mode:
|
|---|
| 1719 | num = SWO_Mode(request, response);
|
|---|
| 1720 | break;
|
|---|
| 1721 | case ID_DAP_SWO_Baudrate:
|
|---|
| 1722 | num = SWO_Baudrate(request, response);
|
|---|
| 1723 | break;
|
|---|
| 1724 | case ID_DAP_SWO_Control:
|
|---|
| 1725 | num = SWO_Control(request, response);
|
|---|
| 1726 | break;
|
|---|
| 1727 | case ID_DAP_SWO_Status:
|
|---|
| 1728 | num = SWO_Status(response);
|
|---|
| 1729 | break;
|
|---|
| 1730 | case ID_DAP_SWO_ExtendedStatus:
|
|---|
| 1731 | num = SWO_ExtendedStatus(request, response);
|
|---|
| 1732 | break;
|
|---|
| 1733 | case ID_DAP_SWO_Data:
|
|---|
| 1734 | num = SWO_Data(request, response);
|
|---|
| 1735 | break;
|
|---|
| 1736 | #endif
|
|---|
| 1737 |
|
|---|
| 1738 | #if (DAP_UART != 0)
|
|---|
| 1739 | case ID_DAP_UART_Transport:
|
|---|
| 1740 | num = UART_Transport(request, response);
|
|---|
| 1741 | break;
|
|---|
| 1742 | case ID_DAP_UART_Configure:
|
|---|
| 1743 | num = UART_Configure(request, response);
|
|---|
| 1744 | break;
|
|---|
| 1745 | case ID_DAP_UART_Control:
|
|---|
| 1746 | num = UART_Control(request, response);
|
|---|
| 1747 | break;
|
|---|
| 1748 | case ID_DAP_UART_Status:
|
|---|
| 1749 | num = UART_Status(response);
|
|---|
| 1750 | break;
|
|---|
| 1751 | case ID_DAP_UART_Transfer:
|
|---|
| 1752 | num = UART_Transfer(request, response);
|
|---|
| 1753 | break;
|
|---|
| 1754 | #endif
|
|---|
| 1755 |
|
|---|
| 1756 | default:
|
|---|
| 1757 | *(response-1) = ID_DAP_Invalid;
|
|---|
| 1758 | return ((1U << 16) | 1U);
|
|---|
| 1759 | }
|
|---|
| 1760 |
|
|---|
| 1761 | return ((1U << 16) + 1U + num);
|
|---|
| 1762 | }
|
|---|
| 1763 |
|
|---|
| 1764 |
|
|---|
| 1765 | // Execute DAP command (process request and prepare response)
|
|---|
| 1766 | // request: pointer to request data
|
|---|
| 1767 | // response: pointer to response data
|
|---|
| 1768 | // return: number of bytes in response (lower 16 bits)
|
|---|
| 1769 | // number of bytes in request (upper 16 bits)
|
|---|
| 1770 | uint32_t DAP_ExecuteCommand(const uint8_t *request, uint8_t *response) {
|
|---|
| 1771 | uint32_t cnt, num, n;
|
|---|
| 1772 |
|
|---|
| 1773 | if (*request == ID_DAP_ExecuteCommands) {
|
|---|
| 1774 | *response++ = *request++;
|
|---|
| 1775 | cnt = *request++;
|
|---|
| 1776 | *response++ = (uint8_t)cnt;
|
|---|
| 1777 | num = (2U << 16) | 2U;
|
|---|
| 1778 | while (cnt--) {
|
|---|
| 1779 | n = DAP_ProcessCommand(request, response);
|
|---|
| 1780 | num += n;
|
|---|
| 1781 | request += (uint16_t)(n >> 16);
|
|---|
| 1782 | response += (uint16_t) n;
|
|---|
| 1783 | }
|
|---|
| 1784 | return (num);
|
|---|
| 1785 | }
|
|---|
| 1786 |
|
|---|
| 1787 | return DAP_ProcessCommand(request, response);
|
|---|
| 1788 | }
|
|---|
| 1789 |
|
|---|
| 1790 |
|
|---|
| 1791 | // Setup DAP
|
|---|
| 1792 | void DAP_Setup(void) {
|
|---|
| 1793 |
|
|---|
| 1794 | // Default settings
|
|---|
| 1795 | DAP_Data.debug_port = 0U;
|
|---|
| 1796 | DAP_Data.transfer.idle_cycles = 0U;
|
|---|
| 1797 | DAP_Data.transfer.retry_count = 100U;
|
|---|
| 1798 | DAP_Data.transfer.match_retry = 0U;
|
|---|
| 1799 | DAP_Data.transfer.match_mask = 0x00000000U;
|
|---|
| 1800 | #if (DAP_SWD != 0)
|
|---|
| 1801 | DAP_Data.swd_conf.turnaround = 1U;
|
|---|
| 1802 | DAP_Data.swd_conf.data_phase = 0U;
|
|---|
| 1803 | #endif
|
|---|
| 1804 | #if (DAP_JTAG != 0)
|
|---|
| 1805 | DAP_Data.jtag_dev.count = 0U;
|
|---|
| 1806 | #endif
|
|---|
| 1807 |
|
|---|
| 1808 | // Sets DAP_Data.fast_clock and DAP_Data.clock_delay.
|
|---|
| 1809 | Set_Clock_Delay(DAP_DEFAULT_SWJ_CLOCK);
|
|---|
| 1810 |
|
|---|
| 1811 | DAP_SETUP(); // Device specific setup
|
|---|
| 1812 | }
|
|---|