Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
source/daplink/cmsis-dap/DAP.c@0:01f31e923fe2, 2020-04-07 (annotated)
- 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?
User | Revision | Line number | New 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 | } |