OpenOCD
swd.c
Go to the documentation of this file.
1 /*
2  * This file is part of the libjaylink project.
3  *
4  * Copyright (C) 2014-2015 Marc Schink <jaylink-dev@marcschink.de>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <stdint.h>
21 #include <stdbool.h>
22 
23 #include "libjaylink.h"
24 #include "libjaylink-internal.h"
25 
33 #define CMD_SWD_IO 0xcf
34 
39 #define SWD_IO_ERR_NO_MEMORY 0x06
40 
72  const uint8_t *direction, const uint8_t *out, uint8_t *in,
73  uint16_t length)
74 {
75  int ret;
76  struct jaylink_context *ctx;
77  uint16_t num_bytes;
78  uint8_t buf[4];
79  uint8_t status;
80 
81  if (!devh || !direction || !out || !in || !length)
82  return JAYLINK_ERR_ARG;
83 
84  ctx = devh->dev->ctx;
85  num_bytes = (length + 7) / 8;
86 
87  ret = transport_start_write_read(devh, 4 + 2 * num_bytes,
88  num_bytes + 1, true);
89 
90  if (ret != JAYLINK_OK) {
91  log_err(ctx, "transport_start_write_read() failed: %s.",
92  jaylink_strerror(ret));
93  return ret;
94  }
95 
96  buf[0] = CMD_SWD_IO;
97  buf[1] = 0x00;
98  buffer_set_u16(buf, length, 2);
99 
100  ret = transport_write(devh, buf, 4);
101 
102  if (ret != JAYLINK_OK) {
103  log_err(ctx, "transport_write() failed: %s.",
104  jaylink_strerror(ret));
105  return ret;
106  }
107 
108  ret = transport_write(devh, direction, num_bytes);
109 
110  if (ret != JAYLINK_OK) {
111  log_err(ctx, "transport_write() failed: %s.",
112  jaylink_strerror(ret));
113  return ret;
114  }
115 
116  ret = transport_write(devh, out, num_bytes);
117 
118  if (ret != JAYLINK_OK) {
119  log_err(ctx, "transport_write() failed: %s.",
120  jaylink_strerror(ret));
121  return ret;
122  }
123 
124  ret = transport_read(devh, in, num_bytes);
125 
126  if (ret != JAYLINK_OK) {
127  log_err(ctx, "transport_read() failed: %s.",
128  jaylink_strerror(ret));
129  return ret;
130  }
131 
132  ret = transport_read(devh, &status, 1);
133 
134  if (ret != JAYLINK_OK) {
135  log_err(ctx, "transport_read() failed: %s.",
136  jaylink_strerror(ret));
137  return ret;
138  }
139 
140  if (status == SWD_IO_ERR_NO_MEMORY) {
142  } else if (status > 0) {
143  log_err(ctx, "SWD I/O operation failed: 0x%x.", status);
144  return JAYLINK_ERR_DEV;
145  }
146 
147  return JAYLINK_OK;
148 }
static uint16_t direction
Definition: ftdi.c:130
JAYLINK_API int jaylink_swd_io(struct jaylink_device_handle *devh, const uint8_t *direction, const uint8_t *out, uint8_t *in, uint16_t length)
Perform a SWD I/O operation.
Definition: swd.c:71
JAYLINK_PRIV void buffer_set_u16(uint8_t *buffer, uint16_t value, size_t offset)
Write a 16-bit unsigned integer value to a buffer.
Definition: buffer.c:43
JAYLINK_API const char * jaylink_strerror(int error_code)
Return a human-readable description of a libjaylink error code.
Definition: error.c:40