/*
 * Copyright (c) 2018-2019 PHYTEC Messtechnik GmbH
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * This file is based on DAP.c from CMSIS-DAP Source (Revision:    V2.0.0)
 * https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DAP/Firmware
 * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/swdp.h>
#include <stdint.h>

#include <cmsis_dap.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dap, CONFIG_DAP_LOG_LEVEL);

#define DAP_STATE_CONNECTED	0

struct dap_context {
	struct device *swdp_dev;
	atomic_t state;
	uint8_t debug_port;
	uint8_t capabilities;
	uint16_t pkt_size;
	struct {
		/* Idle cycles after transfer */
		uint8_t idle_cycles;
		/* Number of retries after WAIT response */
		uint16_t retry_count;
		/* Number of retries if read value does not match */
		uint16_t match_retry;
		/* Match Mask */
		uint32_t match_mask;
	} transfer;
};

static struct dap_context dap_ctx[1];

BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "PROBE_VENDOR string is too long.");
BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_PROBE_NAME) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "PROBE_NAME string is too long.");
BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "BOARD_VENDOR string is too long.");
BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_BOARD_NAME) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "BOARD_NAME string is too long.");
BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "DEVICE_VENDOR string is too long.");
BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME) <=
	     MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
	     "DEVICE_NAME string is too long.");

/* Get DAP Information */
static uint16_t dap_info(struct dap_context *const ctx,
			 const uint8_t *const request,
			 uint8_t *const response)
{
	uint8_t *info = response + 1;
	uint8_t id = request[0];
	uint8_t length = 0U;

	switch (id) {
	case DAP_ID_VENDOR:
		LOG_DBG("ID_VENDOR");
		memcpy(info, CONFIG_CMSIS_DAP_PROBE_VENDOR,
		      sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR));
		length = sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR);
		break;
	case DAP_ID_PRODUCT:
		LOG_DBG("ID_PRODUCT");
		memcpy(info, CONFIG_CMSIS_DAP_PROBE_NAME,
		      sizeof(CONFIG_CMSIS_DAP_PROBE_NAME));
		length = 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:
		LOG_DBG("ID_FW_VER");
		memcpy(info, DAP_FW_VER, sizeof(DAP_FW_VER));
		length = sizeof(DAP_FW_VER);
		break;
	case DAP_ID_DEVICE_VENDOR:
		LOG_DBG("ID_DEVICE_VENDOR");
		memcpy(info, CONFIG_CMSIS_DAP_DEVICE_VENDOR,
		      sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR));
		length = sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR);
		break;
	case DAP_ID_DEVICE_NAME:
		LOG_DBG("ID_DEVICE_NAME");
		memcpy(info, CONFIG_CMSIS_DAP_DEVICE_NAME,
		      sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME));
		length = 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 = 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 = 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;
	case DAP_ID_PACKET_SIZE:
		LOG_DBG("ID_PACKET_SIZE");
		sys_put_le16(ctx->pkt_size, &info[0]);
		length = 2U;
		break;
	case DAP_ID_PACKET_COUNT:
		LOG_DBG("ID_PACKET_COUNT");
		info[0] = CONFIG_CMSIS_DAP_PACKET_COUNT;
		length = 1U;
		break;
	default:
		LOG_DBG("unsupported ID");
		break;
	}

	response[0] = length;

	return length + 1U;
}

/* Process Host Status command and prepare response */
static uint16_t dap_host_status(struct dap_context *const ctx,
				const uint8_t *const request,
				uint8_t *const response)
{
	switch (request[0]) {
	case DAP_DEBUGGER_CONNECTED:
		if (request[1]) {
			LOG_INF("Debugger connected");
		} else {
			LOG_INF("Debugger disconnected");
		}
		break;
	case DAP_TARGET_RUNNING:
		LOG_DBG("unsupported");
		break;
	default:
		*response = DAP_ERROR;
		return 1U;
	}

	response[0] = DAP_OK;
	return 1U;
}

/* Process Connect command and prepare response */
static uint16_t dap_connect(struct dap_context *const ctx,
			    const uint8_t *const request,
			    uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint8_t port;

	if (request[0] == DAP_PORT_AUTODETECT) {
		port = DAP_PORT_SWD;
	} else {
		port = request[0];
	}

	switch (port) {
	case DAP_PORT_SWD:
		LOG_INF("port swd");
		ctx->debug_port = DAP_PORT_SWD;

		if (atomic_test_and_set_bit(&ctx->state,
					    DAP_STATE_CONNECTED)) {
			LOG_ERR("DAP device is already connected");
			break;
		}

		api->swdp_port_on(ctx->swdp_dev);
		break;
	case DAP_PORT_JTAG:
		LOG_ERR("port unsupported");
		port = DAP_ERROR;
		break;
	default:
		LOG_DBG("port disabled");
		port = DAP_PORT_DISABLED;
		break;
	}

	response[0] = port;
	return 1U;
}

/* Process Disconnect command and prepare response */
static uint16_t dap_disconnect(struct dap_context *const ctx,
			       uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;

	LOG_DBG("");

	ctx->debug_port = DAP_PORT_DISABLED;

	if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		api->swdp_port_off(ctx->swdp_dev);
	} else {
		LOG_WRN("DAP device is not connected");
	}

	response[0] = DAP_OK;
	atomic_clear_bit(&ctx->state, DAP_STATE_CONNECTED);

	return 1;
}

/* Process Delay command and prepare response */
static uint16_t dap_delay(struct dap_context *const ctx,
			  const uint8_t *const request,
			  uint8_t *const response)
{
	uint16_t delay = sys_get_le16(&request[0]);

	LOG_DBG("dap delay %u ms", delay);

	k_busy_wait(delay * USEC_PER_MSEC);
	response[0] = DAP_OK;

	return 1U;
}

/* Process Reset Target command and prepare response */
static uint16_t dap_reset_target(struct dap_context *const ctx,
				 uint8_t *const response)
{
	response[0] = DAP_OK;
	response[1] = 0U;
	LOG_WRN("unsupported");

	return 2;
}

/* Process SWJ Pins command and prepare response */
static uint16_t dap_swj_pins(struct dap_context *const ctx,
			     const uint8_t *const request,
			     uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint8_t value = request[0];
	uint8_t select = request[1];
	uint32_t wait = sys_get_le32(&request[2]);
	k_timepoint_t end = sys_timepoint_calc(K_USEC(wait));
	uint8_t state;

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		response[0] = DAP_ERROR;
		return 1U;
	}

	/* Skip if nothing selected. */
	if (select) {
		api->swdp_set_pins(ctx->swdp_dev, select, value);
	}

	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 (!sys_timepoint_expired(end));

	response[0] = state;

	return sizeof(state);
}

/* Process SWJ Clock command and prepare response */
static uint16_t dap_swj_clock(struct dap_context *const ctx,
			      const uint8_t *const request,
			      uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint32_t clk = sys_get_le32(&request[0]);

	LOG_DBG("clock %d", clk);

	if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		if (clk) {
			api->swdp_set_clock(ctx->swdp_dev, clk);
			response[0] = DAP_OK;
		} else {
			response[0] = DAP_ERROR;
		}
	} else {
		LOG_WRN("DAP device is not connected");
		response[0] = DAP_OK;
	}

	return 1U;
}

/* Process SWJ Sequence command and prepare response */
static uint16_t dap_swj_sequence(struct dap_context *const ctx,
				 const uint8_t *const request,
				 uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint16_t count = request[0];

	LOG_DBG("count %u", count);

	if (count == 0U) {
		count = 256U;
	}

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		response[0] = DAP_ERROR;
		return 1U;
	}

	api->swdp_output_sequence(ctx->swdp_dev, count, &request[1]);
	response[0] = DAP_OK;

	return 1U;
}

/* Process SWD Configure command and prepare response */
static uint16_t dap_swdp_configure(struct dap_context *const ctx,
				  const uint8_t *const request,
				  uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint8_t turnaround = (request[0] & 0x03U) + 1U;
	bool data_phase = (request[0] & 0x04U) ? true : false;

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		response[0] = DAP_ERROR;
		return 1U;
	}

	api->swdp_configure(ctx->swdp_dev, turnaround, data_phase);
	response[0] = DAP_OK;

	return 1U;
}

/* Process Transfer Configure command and prepare response */
static uint16_t dap_transfer_cfg(struct dap_context *const ctx,
				 const uint8_t *const request,
				 uint8_t *const response)
{

	ctx->transfer.idle_cycles = request[0];
	ctx->transfer.retry_count = sys_get_le16(&request[1]);
	ctx->transfer.match_retry = sys_get_le16(&request[3]);
	LOG_DBG("idle_cycles %d, retry_count %d, match_retry %d",
		ctx->transfer.idle_cycles,
		ctx->transfer.retry_count,
		ctx->transfer.match_retry);

	response[0] = DAP_OK;
	return 1U;
}

static inline uint8_t do_swdp_transfer(struct dap_context *const ctx,
				      const uint8_t req_val,
				      uint32_t *data)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	uint32_t retry = ctx->transfer.retry_count;
	uint8_t rspns_val;

	do {
		api->swdp_transfer(ctx->swdp_dev,
				   req_val,
				   data,
				   ctx->transfer.idle_cycles,
				   &rspns_val);
	} while ((rspns_val == SWDP_ACK_WAIT) && retry--);

	return rspns_val;
}

static uint8_t swdp_transfer_match(struct dap_context *const ctx,
				  const uint8_t req_val,
				  const uint32_t match_val)
{
	uint32_t match_retry = ctx->transfer.match_retry;
	uint32_t data;
	uint8_t rspns_val;

	if (req_val & SWDP_REQUEST_APnDP) {
		/* Post AP read, result will be returned on the next transfer */
		rspns_val = do_swdp_transfer(ctx, req_val, NULL);
		if (rspns_val != SWDP_ACK_OK) {
			return rspns_val;
		}
	}

	do {
		/*
		 * Read register until its value matches
		 * or retry counter expires
		 */
		rspns_val = do_swdp_transfer(ctx, req_val, &data);
		if (rspns_val != SWDP_ACK_OK) {
			return rspns_val;
		}

	} while (((data & ctx->transfer.match_mask) != match_val) &&
		 match_retry--);

	if ((data & ctx->transfer.match_mask) != match_val) {
		rspns_val |= DAP_TRANSFER_MISMATCH;
	}

	return rspns_val;
}

/*
 * Process SWD Transfer command and prepare response
 * pyOCD counterpart is _encode_transfer_data.
 * Packet format: one byte DAP_index (ignored)
 *                one bytes transfer_count
 *                following by number transfer_count pairs of
 *                    one byte request (register)
 *                    four byte data (for write request only)
 */
static uint16_t dap_swdp_transfer(struct dap_context *const ctx,
				 const uint8_t *const request,
				 uint8_t *const response)
{
	uint8_t *rspns_buf;
	const uint8_t *req_buf;
	uint8_t rspns_cnt = 0;
	uint8_t rspns_val = 0;
	bool post_read = false;
	uint32_t check_write = 0;
	uint8_t req_cnt;
	uint8_t req_val;
	uint32_t match_val;
	uint32_t data;

	/* Ignore DAP index request[0] */
	req_cnt = request[1];
	req_buf = request + sizeof(req_cnt) + 1;
	rspns_buf = response + (sizeof(rspns_cnt) + sizeof(rspns_val));

	for (; req_cnt; req_cnt--) {
		req_val = *req_buf++;
		if (req_val & SWDP_REQUEST_RnW) {
			/* Read register */
			if (post_read) {
				/*
				 * Read was posted before, read previous AP
				 * data or post next AP read.
				 */
				if ((req_val & (SWDP_REQUEST_APnDP |
						DAP_TRANSFER_MATCH_VALUE)) !=
				    SWDP_REQUEST_APnDP) {
					req_val = DP_RDBUFF | SWDP_REQUEST_RnW;
					post_read = false;
				}

				rspns_val = do_swdp_transfer(ctx, req_val, &data);
				if (rspns_val != SWDP_ACK_OK) {
					break;
				}

				/* Store previous AP data */
				sys_put_le32(data, rspns_buf);
				rspns_buf += sizeof(data);
			}
			if (req_val & DAP_TRANSFER_MATCH_VALUE) {
				LOG_INF("match value read");
				/* Read with value match */
				match_val = sys_get_le32(req_buf);
				req_buf += sizeof(match_val);

				rspns_val = swdp_transfer_match(ctx, req_val, match_val);
				if (rspns_val != SWDP_ACK_OK) {
					break;
				}

			} else if (req_val & SWDP_REQUEST_APnDP) {
				/* Normal read */
				if (!post_read) {
					/* Post AP read */
					rspns_val = do_swdp_transfer(ctx, req_val, NULL);
					if (rspns_val != SWDP_ACK_OK) {
						break;
					}
					post_read = true;
				}
			} else {
				/* Read DP register */
				rspns_val = do_swdp_transfer(ctx, req_val, &data);
				if (rspns_val != SWDP_ACK_OK) {
					break;
				}
				/* Store data */
				sys_put_le32(data, rspns_buf);
				rspns_buf += sizeof(data);
			}
			check_write = 0U;
		} else {
			/* Write register */
			if (post_read) {
				/* Read previous data */
				rspns_val = do_swdp_transfer(ctx,
							     DP_RDBUFF | SWDP_REQUEST_RnW,
							     &data);
				if (rspns_val != SWDP_ACK_OK) {
					break;
				}

				/* Store previous data */
				sys_put_le32(data, rspns_buf);
				rspns_buf += sizeof(data);
				post_read = false;
			}
			/* Load data */
			data = sys_get_le32(req_buf);
			req_buf += sizeof(data);
			if (req_val & DAP_TRANSFER_MATCH_MASK) {
				/* Write match mask */
				ctx->transfer.match_mask = data;
				rspns_val = SWDP_ACK_OK;
			} else {
				/* Write DP/AP register */
				rspns_val = do_swdp_transfer(ctx, req_val, &data);
				if (rspns_val != SWDP_ACK_OK) {
					break;
				}

				check_write = 1U;
			}
		}
		rspns_cnt++;
	}

	if (rspns_val == SWDP_ACK_OK) {
		if (post_read) {
			/* Read previous data */
			rspns_val = do_swdp_transfer(ctx,
						     DP_RDBUFF | SWDP_REQUEST_RnW,
						     &data);
			if (rspns_val != SWDP_ACK_OK) {
				goto end;
			}

			/* Store previous data */
			sys_put_le32(data, rspns_buf);
			rspns_buf += sizeof(data);
		} else if (check_write) {
			/* Check last write */
			rspns_val = do_swdp_transfer(ctx,
						     DP_RDBUFF | SWDP_REQUEST_RnW,
						     NULL);
		}
	}

end:
	response[0] = rspns_cnt;
	response[1] = rspns_val;

	return (rspns_buf - response);
}

/* Delegate DAP Transfer command */
static uint16_t dap_transfer(struct dap_context *const ctx,
			     const uint8_t *const request,
			     uint8_t *const response)
{
	uint16_t retval;

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		response[0] = DAP_ERROR;
		return 1U;
	}

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

	return retval;
}

static uint16_t dap_swdp_sequence(struct dap_context *const ctx,
				  const uint8_t *const request,
				  uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	const uint8_t *request_data = request + 1;
	uint8_t *response_data = response + 1;
	uint8_t count = request[0];
	uint8_t num_cycles;
	uint32_t num_bytes;
	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 < count; ++i) {
		input = *request_data & BIT(7);
		num_cycles = *request_data & BIT_MASK(7);
		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.
 * Packet format: one byte DAP_index (ignored)
 *                two bytes transfer_count
 *                one byte block_request (register)
 *                data[transfer_count * sizeof(uint32_t)]
 */
static uint16_t dap_swdp_transferblock(struct dap_context *const ctx,
				      const uint8_t *const request,
				      uint8_t *const response)
{
	uint32_t data;
	uint8_t *rspns_buf;
	const uint8_t *req_buf;
	uint16_t rspns_cnt = 0;
	uint16_t req_cnt;
	uint8_t rspns_val = 0;
	uint8_t req_val;

	req_cnt = sys_get_le16(&request[1]);
	req_val = request[3];
	req_buf = request + (sizeof(req_cnt) + sizeof(req_val) + 1);
	rspns_buf = response + (sizeof(rspns_cnt) + sizeof(rspns_val));

	if (req_cnt == 0U) {
		goto end;
	}

	if (req_val & SWDP_REQUEST_RnW) {
		/* Read register block */
		if (req_val & SWDP_REQUEST_APnDP) {
			/* Post AP read */
			rspns_val = do_swdp_transfer(ctx, req_val, NULL);
			if (rspns_val != SWDP_ACK_OK) {
				goto end;
			}
		}

		while (req_cnt--) {
			/* Read DP/AP register */
			if ((req_cnt == 0U) &&
			    (req_val & SWDP_REQUEST_APnDP)) {
				/* Last AP read */
				req_val = DP_RDBUFF | SWDP_REQUEST_RnW;
			}

			rspns_val = do_swdp_transfer(ctx, req_val, &data);
			if (rspns_val != SWDP_ACK_OK) {
				goto end;
			}

			/* Store data */
			sys_put_le32(data, rspns_buf);
			rspns_buf += sizeof(data);
			rspns_cnt++;
		}
	} else {
		/* Write register block */
		while (req_cnt--) {
			/* Load data */
			data = sys_get_le32(req_buf);
			req_buf += sizeof(data);
			/* Write DP/AP register */
			rspns_val = do_swdp_transfer(ctx, req_val, &data);
			if (rspns_val != SWDP_ACK_OK) {
				goto end;
			}

			rspns_cnt++;
		}
		/* Check last write */
		rspns_val = do_swdp_transfer(ctx, DP_RDBUFF | SWDP_REQUEST_RnW, NULL);
	}

end:
	sys_put_le16(rspns_cnt, &response[0]);
	response[2] = rspns_val;

	LOG_DBG("Received %u, to transmit %u, response count %u",
		req_buf - request,
		rspns_buf - response,
		rspns_cnt * 4);

	return (rspns_buf - response);
}

/* Delegate Transfer Block command */
static uint16_t dap_transferblock(struct dap_context *const ctx,
				  const uint8_t *const request,
				  uint8_t *const response)
{
	uint16_t retval;

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		/* Clear response count */
		sys_put_le16(0U, &response[0]);
		/* Clear DAP response (ACK) value */
		response[2] = 0U;
		return 3U;
	}

	switch (ctx->debug_port) {
	case DAP_PORT_SWD:
		retval = dap_swdp_transferblock(ctx, request, response);
		break;
	case DAP_PORT_JTAG:
	default:
		LOG_ERR("port unsupported");
		/* Clear response count */
		sys_put_le16(0U, &response[0]);
		/* Clear DAP response (ACK) value */
		response[2] = 0U;
		retval = 3U;
	}

	return retval;
}

/* Process SWD Write ABORT command and prepare response */
static uint16_t dap_swdp_writeabort(struct dap_context *const ctx,
				   const uint8_t *const request,
				   uint8_t *const response)
{
	const struct swdp_api *api = ctx->swdp_dev->api;
	/* Load data (Ignore DAP index in request[0]) */
	uint32_t data = sys_get_le32(&request[1]);

	/* Write Abort register */
	api->swdp_transfer(ctx->swdp_dev, DP_ABORT, &data,
			  ctx->transfer.idle_cycles, NULL);

	response[0] = DAP_OK;
	return 1U;
}

/* Delegate DAP Write ABORT command */
static uint16_t dap_writeabort(struct dap_context *const ctx,
			       const uint8_t *const request,
			       uint8_t *const response)
{
	uint16_t retval;

	if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
		LOG_ERR("DAP device is not connected");
		response[0] = DAP_ERROR;
		return 1U;
	}

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

/* Process DAP Vendor command request */
static uint16_t dap_process_vendor_cmd(struct dap_context *const ctx,
				       const uint8_t *const request,
				       uint8_t *const response)
{
	response[0] = ID_DAP_INVALID;
	return 1U;
}

/*
 * Process DAP command request and prepare response
 *   request:  pointer to request data
 *   response: pointer to response data
 *   return:   number of bytes in response
 *
 *   All the subsequent command functions have the same parameter
 *   and return value structure.
 */
static uint16_t dap_process_cmd(struct dap_context *const ctx,
				const uint8_t *request,
				uint8_t *response)
{
	uint16_t retval;

	LOG_HEXDUMP_DBG(request, 8, "req");

	if ((*request >= ID_DAP_VENDOR0) && (*request <= ID_DAP_VENDOR31)) {
		return dap_process_vendor_cmd(ctx, request, response);
	}

	*response++ = *request;
	LOG_DBG("request 0x%02x", *request);

	switch (*request++) {
	case ID_DAP_INFO:
		retval = dap_info(ctx, request, response);
		break;
	case ID_DAP_HOST_STATUS:
		retval = dap_host_status(ctx, request, response);
		break;
	case ID_DAP_CONNECT:
		retval = dap_connect(ctx, request, response);
		break;
	case ID_DAP_DISCONNECT:
		retval = dap_disconnect(ctx, response);
		break;
	case ID_DAP_DELAY:
		retval = dap_delay(ctx, request, response);
		break;
	case ID_DAP_RESET_TARGET:
		retval = dap_reset_target(ctx, response);
		break;
	case ID_DAP_SWJ_PINS:
		retval = dap_swj_pins(ctx, request, response);
		break;
	case ID_DAP_SWJ_CLOCK:
		retval = dap_swj_clock(ctx, request, response);
		break;
	case ID_DAP_SWJ_SEQUENCE:
		retval = dap_swj_sequence(ctx, request, response);
		break;
	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;
		*response = DAP_ERROR;
		break;
	case ID_DAP_JTAG_CONFIGURE:
		LOG_ERR("JTAG configure unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_JTAG_IDCODE:
		LOG_ERR("JTAG IDCODE unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_TRANSFER_CONFIGURE:
		retval = dap_transfer_cfg(ctx, request, response);
		break;
	case ID_DAP_TRANSFER:
		retval = dap_transfer(ctx, request, response);
		break;
	case ID_DAP_TRANSFER_BLOCK:
		retval = dap_transferblock(ctx, request, response);
		break;
	case ID_DAP_WRITE_ABORT:
		retval = dap_writeabort(ctx, request, response);
		break;
	case ID_DAP_SWO_TRANSPORT:
		LOG_ERR("SWO Transport unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_SWO_MODE:
		LOG_ERR("SWO Mode unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_SWO_BAUDRATE:
		LOG_ERR("SWO Baudrate unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_SWO_CONTROL:
		LOG_ERR("SWO Control unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_SWO_STATUS:
		LOG_ERR("SWO Status unsupported");
		retval = 1;
		*response = DAP_ERROR;
		break;
	case ID_DAP_SWO_DATA:
		LOG_ERR("SWO Data unsupported");
		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;
		return 1U;
	}

	return (1U + retval);
}

/*
 * Execute DAP command (process request and prepare response)
 *   request:  pointer to request data
 *   response: pointer to response data
 *   return:   number of bytes in response
 */
uint32_t dap_execute_cmd(const uint8_t *request,
			 uint8_t *response)
{
	uint32_t retval;
	uint16_t n;
	uint8_t count;

	if (request[0] == ID_DAP_EXECUTE_COMMANDS) {
		/* copy command and increment */
		*response++ = *request++;
		count = request[0];
		request += sizeof(count);
		response[0] = count;
		response += sizeof(count);
		retval = sizeof(count) + 1U;
		LOG_WRN("(untested) ID DAP EXECUTE_COMMANDS count %u", count);
		while (count--) {
			n = dap_process_cmd(&dap_ctx[0], request, response);
			retval += n;
			request += n;
			response += n;
		}
		return retval;
	}

	return dap_process_cmd(&dap_ctx[0], request, response);
}

int dap_setup(const struct device *const dev)
{
	dap_ctx[0].swdp_dev = (void *)dev;

	if (!device_is_ready(dap_ctx[0].swdp_dev)) {
		LOG_ERR("SWD driver not ready");
		return -ENODEV;
	}

	/* Default settings */
	dap_ctx[0].pkt_size = CONFIG_CMSIS_DAP_PACKET_SIZE;
	dap_ctx[0].debug_port = 0U;
	dap_ctx[0].transfer.idle_cycles = 0U;
	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_SUPPORTS_SWD;

	return 0;
}
