2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014-2015 Marc Schink <jaylink-dev@marcschink.de>
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.
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.
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/>.
23 #include "libjaylink.h"
24 #include "libjaylink-internal.h"
33 #define CMD_JTAG_IO_V2 0xce
34 #define CMD_JTAG_IO_V3 0xcf
35 #define CMD_JTAG_CLEAR_TRST 0xde
36 #define CMD_JTAG_SET_TRST 0xdf
37 #define CMD_JTAG_CLEAR_TMS 0xc9
38 #define CMD_JTAG_SET_TMS 0xca
39 #define CMD_JTAG_CLEAR_TCK 0xda
40 #define CMD_JTAG_SET_TCK 0xdb
43 * Error code indicating that there is not enough free memory on the device to
44 * perform the JTAG I/O operation.
46 #define JTAG_IO_ERR_NO_MEMORY 0x06
50 * Perform a JTAG I/O operation.
52 * @note This function must only be used if the #JAYLINK_TIF_JTAG interface is
53 * available and selected. Nevertheless, this function can be used if the
54 * device doesn't have the #JAYLINK_DEV_CAP_SELECT_TIF capability.
56 * @param[in,out] devh Device handle.
57 * @param[in] tms Buffer to read TMS data from.
58 * @param[in] tdi Buffer to read TDI data from.
59 * @param[out] tdo Buffer to store TDO data on success. Its content is
60 * undefined on failure. The buffer must be large enough to
61 * contain at least the specified number of bits to transfer.
62 * @param[in] length Number of bits to transfer.
63 * @param[in] version Version of the JTAG command to use.
65 * @retval JAYLINK_OK Success.
66 * @retval JAYLINK_ERR_ARG Invalid arguments.
67 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
68 * @retval JAYLINK_ERR_IO Input/output error.
69 * @retval JAYLINK_ERR_DEV_NO_MEMORY Not enough memory on the device to perform
71 * @retval JAYLINK_ERR_DEV Unspecified device error.
72 * @retval JAYLINK_ERR Other error conditions.
74 * @see jaylink_select_interface()
75 * @see jaylink_set_speed()
79 JAYLINK_API
int jaylink_jtag_io(struct jaylink_device_handle
*devh
,
80 const uint8_t *tms
, const uint8_t *tdi
, uint8_t *tdo
,
81 uint16_t length
, enum jaylink_jtag_version version
)
84 struct jaylink_context
*ctx
;
91 if (!devh
|| !tms
|| !tdi
|| !tdo
|| !length
)
92 return JAYLINK_ERR_ARG
;
94 num_bytes
= (length
+ 7) / 8;
95 read_length
= num_bytes
;
98 case JAYLINK_JTAG_VERSION_2
:
101 case JAYLINK_JTAG_VERSION_3
:
102 cmd
= CMD_JTAG_IO_V3
;
103 /* In this version, the response includes a status byte. */
107 return JAYLINK_ERR_ARG
;
110 ctx
= devh
->dev
->ctx
;
111 ret
= transport_start_write_read(devh
, 4 + 2 * num_bytes
,
114 if (ret
!= JAYLINK_OK
) {
115 log_err(ctx
, "transport_start_write_read() failed: %s",
116 jaylink_strerror(ret
));
122 buffer_set_u16(buf
, length
, 2);
124 ret
= transport_write(devh
, buf
, 4);
126 if (ret
!= JAYLINK_OK
) {
127 log_err(ctx
, "transport_write() failed: %s",
128 jaylink_strerror(ret
));
132 ret
= transport_write(devh
, tms
, num_bytes
);
134 if (ret
!= JAYLINK_OK
) {
135 log_err(ctx
, "transport_write() failed: %s",
136 jaylink_strerror(ret
));
140 ret
= transport_write(devh
, tdi
, num_bytes
);
142 if (ret
!= JAYLINK_OK
) {
143 log_err(ctx
, "transport_write() failed: %s",
144 jaylink_strerror(ret
));
148 ret
= transport_read(devh
, tdo
, num_bytes
);
150 if (ret
!= JAYLINK_OK
) {
151 log_err(ctx
, "transport_read() failed: %s",
152 jaylink_strerror(ret
));
156 if (version
== JAYLINK_JTAG_VERSION_2
)
159 ret
= transport_read(devh
, &status
, 1);
161 if (ret
!= JAYLINK_OK
) {
162 log_err(ctx
, "transport_read() failed: %s",
163 jaylink_strerror(ret
));
167 if (status
== JTAG_IO_ERR_NO_MEMORY
) {
168 return JAYLINK_ERR_DEV_NO_MEMORY
;
169 } else if (status
> 0) {
170 log_err(ctx
, "JTAG I/O operation failed: 0x%x", status
);
171 return JAYLINK_ERR_DEV
;
178 * Clear the JTAG test reset (TRST) signal.
180 * @param[in,out] devh Device handle.
182 * @retval JAYLINK_OK Success.
183 * @retval JAYLINK_ERR_ARG Invalid arguments.
184 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
185 * @retval JAYLINK_ERR_IO Input/output error.
186 * @retval JAYLINK_ERR Other error conditions.
190 JAYLINK_API
int jaylink_jtag_clear_trst(struct jaylink_device_handle
*devh
)
193 struct jaylink_context
*ctx
;
197 return JAYLINK_ERR_ARG
;
199 ctx
= devh
->dev
->ctx
;
200 ret
= transport_start_write(devh
, 1, true);
202 if (ret
!= JAYLINK_OK
) {
203 log_err(ctx
, "transport_start_write() failed: %s",
204 jaylink_strerror(ret
));
208 buf
[0] = CMD_JTAG_CLEAR_TRST
;
210 ret
= transport_write(devh
, buf
, 1);
212 if (ret
!= JAYLINK_OK
) {
213 log_err(ctx
, "transport_write() failed: %s",
214 jaylink_strerror(ret
));
222 * Set the JTAG test reset (TRST) signal.
224 * @param[in,out] devh Device handle.
226 * @retval JAYLINK_OK Success.
227 * @retval JAYLINK_ERR_ARG Invalid arguments.
228 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
229 * @retval JAYLINK_ERR_IO Input/output error.
230 * @retval JAYLINK_ERR Other error conditions.
234 JAYLINK_API
int jaylink_jtag_set_trst(struct jaylink_device_handle
*devh
)
237 struct jaylink_context
*ctx
;
241 return JAYLINK_ERR_ARG
;
243 ctx
= devh
->dev
->ctx
;
244 ret
= transport_start_write(devh
, 1, true);
246 if (ret
!= JAYLINK_OK
) {
247 log_err(ctx
, "transport_start_write() failed: %s",
248 jaylink_strerror(ret
));
252 buf
[0] = CMD_JTAG_SET_TRST
;
254 ret
= transport_write(devh
, buf
, 1);
256 if (ret
!= JAYLINK_OK
) {
257 log_err(ctx
, "transport_write() failed: %s",
258 jaylink_strerror(ret
));
266 * Clear the JTAG test mode select (TMS) signal.
268 * @param[in,out] devh Device handle.
270 * @retval JAYLINK_OK Success.
271 * @retval JAYLINK_ERR_ARG Invalid arguments.
272 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
273 * @retval JAYLINK_ERR_IO Input/output error.
274 * @retval JAYLINK_ERR Other error conditions.
278 JAYLINK_API
int jaylink_jtag_clear_tms(struct jaylink_device_handle
*devh
)
281 struct jaylink_context
*ctx
;
285 return JAYLINK_ERR_ARG
;
287 ctx
= devh
->dev
->ctx
;
288 ret
= transport_start_write(devh
, 1, true);
290 if (ret
!= JAYLINK_OK
) {
291 log_err(ctx
, "transport_start_write() failed: %s",
292 jaylink_strerror(ret
));
296 buf
[0] = CMD_JTAG_CLEAR_TMS
;
298 ret
= transport_write(devh
, buf
, 1);
300 if (ret
!= JAYLINK_OK
) {
301 log_err(ctx
, "transport_write() failed: %s",
302 jaylink_strerror(ret
));
310 * Set the JTAG test mode select (TMS) signal.
312 * @param[in,out] devh Device handle.
314 * @retval JAYLINK_OK Success.
315 * @retval JAYLINK_ERR_ARG Invalid arguments.
316 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
317 * @retval JAYLINK_ERR_IO Input/output error.
318 * @retval JAYLINK_ERR Other error conditions.
322 JAYLINK_API
int jaylink_jtag_set_tms(struct jaylink_device_handle
*devh
)
325 struct jaylink_context
*ctx
;
329 return JAYLINK_ERR_ARG
;
331 ctx
= devh
->dev
->ctx
;
332 ret
= transport_start_write(devh
, 1, true);
334 if (ret
!= JAYLINK_OK
) {
335 log_err(ctx
, "transport_start_write() failed: %s",
336 jaylink_strerror(ret
));
340 buf
[0] = CMD_JTAG_SET_TMS
;
342 ret
= transport_write(devh
, buf
, 1);
344 if (ret
!= JAYLINK_OK
) {
345 log_err(ctx
, "transport_write() failed: %s",
346 jaylink_strerror(ret
));
354 * Clear the JTAG test clock (TCK) signal.
356 * @param[in,out] devh Device handle.
358 * @retval JAYLINK_OK Success.
359 * @retval JAYLINK_ERR_ARG Invalid arguments.
360 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
361 * @retval JAYLINK_ERR_IO Input/output error.
362 * @retval JAYLINK_ERR Other error conditions.
366 JAYLINK_API
int jaylink_jtag_clear_tck(struct jaylink_device_handle
*devh
)
369 struct jaylink_context
*ctx
;
373 return JAYLINK_ERR_ARG
;
375 ctx
= devh
->dev
->ctx
;
376 ret
= transport_start_write(devh
, 1, true);
378 if (ret
!= JAYLINK_OK
) {
379 log_err(ctx
, "transport_start_write() failed: %s",
380 jaylink_strerror(ret
));
384 buf
[0] = CMD_JTAG_CLEAR_TCK
;
386 ret
= transport_write(devh
, buf
, 1);
388 if (ret
!= JAYLINK_OK
) {
389 log_err(ctx
, "transport_write() failed: %s",
390 jaylink_strerror(ret
));
398 * Set the JTAG test clock (TCK) signal.
400 * @param[in,out] devh Device handle.
402 * @retval JAYLINK_OK Success.
403 * @retval JAYLINK_ERR_ARG Invalid arguments.
404 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
405 * @retval JAYLINK_ERR_IO Input/output error.
406 * @retval JAYLINK_ERR Other error conditions.
410 JAYLINK_API
int jaylink_jtag_set_tck(struct jaylink_device_handle
*devh
)
413 struct jaylink_context
*ctx
;
417 return JAYLINK_ERR_ARG
;
419 ctx
= devh
->dev
->ctx
;
420 ret
= transport_start_write(devh
, 1, true);
422 if (ret
!= JAYLINK_OK
) {
423 log_err(ctx
, "transport_start_write() failed: %s",
424 jaylink_strerror(ret
));
428 buf
[0] = CMD_JTAG_SET_TCK
;
430 ret
= transport_write(devh
, buf
, 1);
432 if (ret
!= JAYLINK_OK
) {
433 log_err(ctx
, "transport_write() failed: %s",
434 jaylink_strerror(ret
));