Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

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