Skip to content

Commit

Permalink
dap: update protocol to v2.1.0
Browse files Browse the repository at this point in the history
Signed-off-by: Maximilian Deubel <[email protected]>
  • Loading branch information
maxd-nordic committed Jul 4, 2023
1 parent 0dc22e6 commit 8837a59
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 27 deletions.
24 changes: 24 additions & 0 deletions subsys/dap/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ config CMSIS_DAP_PACKET_SIZE
help
Maximum packet size for request and response data.

config CMSIS_DAP_PROBE_VENDOR
string "Probe vendor"
default "Zephyr"

config CMSIS_DAP_PROBE_NAME
string "Probe name"
default "CMSIS-DAP"

config CMSIS_DAP_BOARD_VENDOR
string "Target board vendor"
default ""

config CMSIS_DAP_BOARD_NAME
string "Target board name"
default ""

config CMSIS_DAP_DEVICE_VENDOR
string "Target device vendor"
default ""

config CMSIS_DAP_DEVICE_NAME
string "Target device name"
default ""

module = DAP
module-str = dap
source "subsys/logging/Kconfig.template.log_config"
Expand Down
141 changes: 126 additions & 15 deletions subsys/dap/cmsis_dap.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dap, CONFIG_DAP_LOG_LEVEL);

const char dap_fw_ver[] = DAP_FW_VER;

#define DAP_STATE_CONNECTED 0

struct dap_context {
Expand Down Expand Up @@ -59,30 +57,62 @@ static uint16_t dap_info(struct dap_context *const ctx,

switch (id) {
case DAP_ID_VENDOR:
LOG_DBG("ID_VENDOR unsupported");
LOG_DBG("ID_VENDOR");
memcpy(info, CONFIG_CMSIS_DAP_PROBE_VENDOR, sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR);
break;
case DAP_ID_PRODUCT:
LOG_DBG("ID_PRODUCT unsupported");
LOG_DBG("ID_PRODUCT");
memcpy(info, CONFIG_CMSIS_DAP_PROBE_NAME, sizeof(CONFIG_CMSIS_DAP_PROBE_NAME));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_PROBE_NAME);
break;
case DAP_ID_SER_NUM:
/* optional to implement */
LOG_DBG("ID_SER_NUM unsupported");
break;
case DAP_ID_FW_VER:
case DAP_ID_DAP_FW_VER:
LOG_DBG("ID_FW_VER");
memcpy(info, dap_fw_ver, sizeof(dap_fw_ver));
length = (uint8_t)sizeof(dap_fw_ver);
memcpy(info, DAP_FW_VER, sizeof(DAP_FW_VER));
length = (uint8_t)sizeof(DAP_FW_VER);
break;
case DAP_ID_DEVICE_VENDOR:
LOG_DBG("ID_DEVICE_VENDOR unsupported");
LOG_DBG("ID_DEVICE_VENDOR");
memcpy(info, CONFIG_CMSIS_DAP_DEVICE_VENDOR, sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR);
break;
case DAP_ID_DEVICE_NAME:
LOG_DBG("ID_DEVICE_NAME unsupported");
LOG_DBG("ID_DEVICE_NAME");
memcpy(info, CONFIG_CMSIS_DAP_DEVICE_NAME, sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME);
break;
case DAP_ID_BOARD_VENDOR:
LOG_DBG("ID_BOARD_VENDOR");
memcpy(info, CONFIG_CMSIS_DAP_BOARD_VENDOR, sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR);
break;
case DAP_ID_BOARD_NAME:
memcpy(info, CONFIG_CMSIS_DAP_BOARD_NAME, sizeof(CONFIG_CMSIS_DAP_BOARD_NAME));
length = (uint8_t)sizeof(CONFIG_CMSIS_DAP_BOARD_NAME);
LOG_DBG("ID_BOARD_NAME");
break;
case DAP_ID_PRODUCT_FW_VER:
/* optional to implement */
LOG_DBG("ID_PRODUCT_FW_VER unsupported");
break;
case DAP_ID_CAPABILITIES:
info[0] = ctx->capabilities;
LOG_DBG("ID_CAPABILITIES 0x%0x", info[0]);
length = 1U;
break;
case DAP_ID_TIMESTAMP_CLOCK:
LOG_DBG("ID_TIMESTAMP_CLOCK unsupported");
break;
case DAP_ID_UART_RX_BUFFER_SIZE:
LOG_DBG("ID_UART_RX_BUFFER_SIZE unsupported");
break;
case DAP_ID_UART_TX_BUFFER_SIZE:
LOG_DBG("ID_UART_TX_BUFFER_SIZE unsupported");
break;
case DAP_ID_SWO_BUFFER_SIZE:
LOG_DBG("ID_SWO_BUFFER_SIZE unsupported");
break;
Expand Down Expand Up @@ -209,6 +239,7 @@ static uint16_t dap_delay(struct dap_context *const ctx,
static uint16_t dap_reset_target(struct dap_context *const ctx,
uint8_t *const response)
{
/* do a device specific reset sequence - optional */
response[0] = DAP_OK;
response[1] = 0U;
LOG_WRN("unsupported");
Expand All @@ -226,6 +257,7 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx,
uint8_t select = request[1];
uint32_t wait = sys_get_le32(&request[2]);
uint8_t state;
int64_t timout_ticks = k_uptime_ticks() + (CONFIG_SYS_CLOCK_TICKS_PER_SEC / 1000000 * wait);

if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
LOG_ERR("DAP device is not connected");
Expand All @@ -238,10 +270,16 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx,
api->swdp_set_pins(ctx->swdp_dev, select, value);
}

/* TODO: implement wait */
api->swdp_get_pins(ctx->swdp_dev, &state);
LOG_ERR("select 0x%02x, value 0x%02x, wait %u, state 0x%02x",
select, value, wait, state);
do
{
api->swdp_get_pins(ctx->swdp_dev, &state);
LOG_INF("select 0x%02x, value 0x%02x, wait %u, state 0x%02x",
select, value, wait, state);
if ((value & select) == (state & select)) {
LOG_DBG("swdp_get_pins succeeded before timeout");
break;
}
} while (k_uptime_ticks() - timout_ticks > 0);

response[0] = state;

Expand Down Expand Up @@ -570,6 +608,50 @@ static uint16_t dap_transfer(struct dap_context *const ctx,
return retval;
}

static uint16_t dap_swdp_sequence(struct dap_context *const ctx,
const uint8_t *const request,
uint8_t *const response)
{
uint8_t sequence_count = request[0];
uint8_t num_cycles;
uint32_t num_bytes;
const struct swdp_api *api = ctx->swdp_dev->api;
const uint8_t *request_data = request + 1;
uint8_t *response_data = response + 1;
bool input;

switch (ctx->debug_port) {
case DAP_PORT_SWD:
response[0] = DAP_OK;
break;
case DAP_PORT_JTAG:
default:
LOG_ERR("port unsupported");
response[0] = DAP_ERROR;
return 1U;
}

for (size_t i = 0; i < sequence_count; ++i) {
input = *request_data & 0x80;
num_cycles = *request_data & 0x3F;
num_bytes = (num_cycles + 7) >> 3; /* rounded up to full bytes */
if (num_cycles == 0) {
num_cycles = 64;
}
request_data += 1;

if (input) {
api->swdp_input_sequence(ctx->swdp_dev, num_cycles, response_data);
response_data += num_bytes;
} else {
api->swdp_output_sequence(ctx->swdp_dev, num_cycles, request_data);
request_data += num_bytes;
}
}

return response_data - response;
}

/*
* Process SWD DAP_TransferBlock command and prepare response.
* pyOCD counterpart is _encode_transfer_block_data.
Expand Down Expand Up @@ -802,6 +884,9 @@ static uint16_t dap_process_cmd(struct dap_context *const ctx,
case ID_DAP_SWDP_CONFIGURE:
retval = dap_swdp_configure(ctx, request, response);
break;
case ID_DAP_SWDP_SEQUENCE:
retval = dap_swdp_sequence(ctx, request, response);
break;
case ID_DAP_JTAG_SEQUENCE:
LOG_ERR("JTAG sequence unsupported");
retval = 1;
Expand Down Expand Up @@ -859,6 +944,31 @@ static uint16_t dap_process_cmd(struct dap_context *const ctx,
retval = 1;
*response = DAP_ERROR;
break;
case ID_DAP_UART_Transport:
LOG_ERR("UART Transport unsupported");
retval = 1;
*response = DAP_ERROR;
break;
case ID_DAP_UART_Configure:
LOG_ERR("UART Configure unsupported");
retval = 1;
*response = DAP_ERROR;
break;
case ID_DAP_UART_Control:
LOG_ERR("UART Control unsupported");
retval = 1;
*response = DAP_ERROR;
break;
case ID_DAP_UART_Status:
LOG_ERR("UART Status unsupported");
retval = 1;
*response = DAP_ERROR;
break;
case ID_DAP_UART_Transfer:
LOG_ERR("UART Transfer unsupported");
retval = 1;
*response = DAP_ERROR;
break;

default:
*(response - 1) = ID_DAP_INVALID;
Expand Down Expand Up @@ -924,8 +1034,9 @@ int dap_setup(const struct device *const dev)
dap_ctx[0].transfer.retry_count = 100U;
dap_ctx[0].transfer.match_retry = 0U;
dap_ctx[0].transfer.match_mask = 0U;
dap_ctx[0].capabilities = DAP_SUPPORTS_ATOMIC_COMMANDS |
DAP_DP_SUPPOTS_SWD;
dap_ctx[0].capabilities =
DAP_SUPPORTS_ATOMIC_COMMANDS |
DAP_DP_SUPPOTS_SWD;

return 0;
}
41 changes: 29 additions & 12 deletions subsys/dap/cmsis_dap.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <zephyr/kernel.h>

/* Firmware Version */
#define DAP_FW_VER "1.10"
#define DAP_FW_VER "2.1.0"

/* DAP Command IDs */
#define ID_DAP_INFO 0x00U
Expand All @@ -35,20 +35,31 @@
#define ID_DAP_WRITE_ABORT 0x08U
#define ID_DAP_DELAY 0x09U
#define ID_DAP_RESET_TARGET 0x0AU

#define ID_DAP_SWJ_PINS 0x10U
#define ID_DAP_SWJ_CLOCK 0x11U
#define ID_DAP_SWJ_SEQUENCE 0x12U

#define ID_DAP_SWDP_CONFIGURE 0x13U
#define ID_DAP_SWDP_SEQUENCE 0x1DU

#define ID_DAP_JTAG_SEQUENCE 0x14U
#define ID_DAP_JTAG_CONFIGURE 0x15U
#define ID_DAP_JTAG_IDCODE 0x16U

#define ID_DAP_SWO_TRANSPORT 0x17U
#define ID_DAP_SWO_MODE 0x18U
#define ID_DAP_SWO_BAUDRATE 0x19U
#define ID_DAP_SWO_CONTROL 0x1AU
#define ID_DAP_SWO_STATUS 0x1BU
#define ID_DAP_SWO_DATA 0x1CU

#define ID_DAP_UART_Transport 0x1FU
#define ID_DAP_UART_Configure 0x20U
#define ID_DAP_UART_Control 0x22U
#define ID_DAP_UART_Status 0x23U
#define ID_DAP_UART_Transfer 0x21U

#define ID_DAP_QUEUE_COMMANDS 0x7EU
#define ID_DAP_EXECUTE_COMMANDS 0x7FU

Expand All @@ -60,30 +71,36 @@
#define ID_DAP_INVALID 0xFFU

/* DAP Status Code */
#define DAP_OK 0U
#define DAP_OK 0x00U
#define DAP_ERROR 0xFFU

/* DAP ID */
#define DAP_ID_VENDOR 0x01U
#define DAP_ID_PRODUCT 0x02U
#define DAP_ID_SER_NUM 0x03U
#define DAP_ID_FW_VER 0x04U
#define DAP_ID_DAP_FW_VER 0x04U
#define DAP_ID_DEVICE_VENDOR 0x05U
#define DAP_ID_DEVICE_NAME 0x06U
#define DAP_ID_BOARD_VENDOR 0x07U
#define DAP_ID_BOARD_NAME 0x08U
#define DAP_ID_PRODUCT_FW_VER 0x09U
#define DAP_ID_CAPABILITIES 0xF0U
#define DAP_ID_TIMESTAMP_CLOCK 0xF1U
#define DAP_ID_UART_RX_BUFFER_SIZE 0xFBU
#define DAP_ID_UART_TX_BUFFER_SIZE 0xFCU
#define DAP_ID_SWO_BUFFER_SIZE 0xFDU
#define DAP_ID_PACKET_COUNT 0xFEU
#define DAP_ID_PACKET_SIZE 0xFFU

/* DAP Host Status */
#define DAP_DEBUGGER_CONNECTED 0U
#define DAP_TARGET_RUNNING 1U
#define DAP_DEBUGGER_CONNECTED 0x00U
#define DAP_TARGET_RUNNING 0x01U

/* DAP Port */
#define DAP_PORT_AUTODETECT 0U
#define DAP_PORT_DISABLED 0U
#define DAP_PORT_SWD 1U
#define DAP_PORT_JTAG 2U
#define DAP_PORT_AUTODETECT 0x00U
#define DAP_PORT_DISABLED 0x00U
#define DAP_PORT_SWD 0x01U
#define DAP_PORT_JTAG 0x02U

/* DAP transfer request bits */
#define DAP_TRANSFER_MATCH_VALUE BIT(4)
Expand All @@ -109,9 +126,9 @@
#define DP_RESEND 0x08U
#define DP_RDBUFF 0x0CU

#define DAP_MBMSG_REGISTER_IFACE 0x0U
#define DAP_MBMSG_FROM_IFACE 0x1U
#define DAP_MBMSG_FROM_CONTROLLER 0x2U
#define DAP_MBMSG_REGISTER_IFACE 0x00U
#define DAP_MBMSG_FROM_IFACE 0x01U
#define DAP_MBMSG_FROM_CONTROLLER 0x02U

typedef int (*dap_vendor_cb_t)(const uint8_t *request,
uint8_t *response);
Expand Down

0 comments on commit 8837a59

Please sign in to comment.