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"
29 * Target related functions.
33 #define CMD_SET_SPEED 0x05
34 #define CMD_SET_TARGET_POWER 0x08
35 #define CMD_GET_SPEEDS 0xc0
36 #define CMD_SELECT_TIF 0xc7
37 #define CMD_CLEAR_RESET 0xdc
38 #define CMD_SET_RESET 0xdd
40 #define TIF_GET_SELECTED 0xfe
41 #define TIF_GET_AVAILABLE 0xff
45 * Set the target interface speed.
47 * @param[in,out] devh Device handle.
48 * @param[in] speed Speed in kHz or #JAYLINK_SPEED_ADAPTIVE_CLOCKING for
49 * adaptive clocking. Speed of 0 kHz is not allowed and
50 * adaptive clocking must only be used if the device has the
51 * #JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING capability.
53 * @retval JAYLINK_OK Success.
54 * @retval JAYLINK_ERR_ARG Invalid arguments.
55 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
56 * @retval JAYLINK_ERR_IO Input/output error.
57 * @retval JAYLINK_ERR Other error conditions.
59 * @see jaylink_get_speeds()
63 JAYLINK_API
int jaylink_set_speed(struct jaylink_device_handle
*devh
,
67 struct jaylink_context
*ctx
;
71 return JAYLINK_ERR_ARG
;
74 ret
= transport_start_write(devh
, 3, true);
76 if (ret
!= JAYLINK_OK
) {
77 log_err(ctx
, "transport_start_write() failed: %s.",
78 jaylink_strerror(ret
));
82 buf
[0] = CMD_SET_SPEED
;
83 buffer_set_u16(buf
, speed
, 1);
85 ret
= transport_write(devh
, buf
, 3);
87 if (ret
!= JAYLINK_OK
) {
88 log_err(ctx
, "transport_write() failed: %s.",
89 jaylink_strerror(ret
));
97 * Retrieve target interface speeds.
99 * The speeds are applicable for the currently selected target interface only
100 * and calculated as follows:
103 * <tt>speeds = @a freq / n</tt> with <tt>n >= @a div</tt>, where @p n is an
106 * Assuming, for example, a base frequency @a freq of 4 MHz and a minimum
107 * divider @a div of 4 then the highest possible target interface speed is
108 * 4 MHz / 4 = 1 MHz. The next highest speed is 800 kHz for a divider of 5, and
111 * @note This function must only be used if the device has the
112 * #JAYLINK_DEV_CAP_GET_SPEEDS capability.
114 * @param[in,out] devh Device handle.
115 * @param[out] speed Speed information on success, and undefined on failure.
117 * @retval JAYLINK_OK Success.
118 * @retval JAYLINK_ERR_ARG Invalid arguments.
119 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
120 * @retval JAYLINK_ERR_PROTO Protocol violation.
121 * @retval JAYLINK_ERR_IO Input/output error.
122 * @retval JAYLINK_ERR Other error conditions.
124 * @see jaylink_select_interface()
128 JAYLINK_API
int jaylink_get_speeds(struct jaylink_device_handle
*devh
,
129 struct jaylink_speed
*speed
)
132 struct jaylink_context
*ctx
;
137 return JAYLINK_ERR_ARG
;
139 ctx
= devh
->dev
->ctx
;
140 ret
= transport_start_write_read(devh
, 1, 6, true);
142 if (ret
!= JAYLINK_OK
) {
143 log_err(ctx
, "transport_start_write_read() failed: %s.",
144 jaylink_strerror(ret
));
148 buf
[0] = CMD_GET_SPEEDS
;
150 ret
= transport_write(devh
, buf
, 1);
152 if (ret
!= JAYLINK_OK
) {
153 log_err(ctx
, "transport_write() failed: %s.",
154 jaylink_strerror(ret
));
158 ret
= transport_read(devh
, buf
, 6);
160 if (ret
!= JAYLINK_OK
) {
161 log_err(ctx
, "transport_read() failed: %s.",
162 jaylink_strerror(ret
));
166 div
= buffer_get_u16(buf
, 4);
169 log_err(ctx
, "Minimum frequency divider is zero.");
170 return JAYLINK_ERR_PROTO
;
173 speed
->freq
= buffer_get_u32(buf
, 0);
180 * Select the target interface.
182 * @note This function must only be used if the device has the
183 * #JAYLINK_DEV_CAP_SELECT_TIF capability.
185 * @warning This function may return a value for @p prev_iface which is not
186 * covered by #jaylink_target_interface.
188 * @param[in,out] devh Device handle.
189 * @param[in] iface Target interface to select.
190 * @param[out] prev_iface Previously selected target interface on success, and
191 * undefined on failure. Can be NULL.
193 * @retval JAYLINK_OK Success.
194 * @retval JAYLINK_ERR_ARG Invalid arguments.
195 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
196 * @retval JAYLINK_ERR_IO Input/output error.
197 * @retval JAYLINK_ERR Other error conditions.
199 * @see jaylink_get_available_interfaces()
203 JAYLINK_API
int jaylink_select_interface(struct jaylink_device_handle
*devh
,
204 enum jaylink_target_interface iface
,
205 enum jaylink_target_interface
*prev_iface
)
208 struct jaylink_context
*ctx
;
212 return JAYLINK_ERR_ARG
;
215 case JAYLINK_TIF_JTAG
:
216 case JAYLINK_TIF_SWD
:
217 case JAYLINK_TIF_BDM3
:
218 case JAYLINK_TIF_FINE
:
219 case JAYLINK_TIF_2W_JTAG_PIC32
:
222 return JAYLINK_ERR_ARG
;
225 ctx
= devh
->dev
->ctx
;
226 ret
= transport_start_write_read(devh
, 2, 4, true);
228 if (ret
!= JAYLINK_OK
) {
229 log_err(ctx
, "transport_start_write_read() failed: %s.",
230 jaylink_strerror(ret
));
234 buf
[0] = CMD_SELECT_TIF
;
237 ret
= transport_write(devh
, buf
, 2);
239 if (ret
!= JAYLINK_OK
) {
240 log_err(ctx
, "transport_write() failed: %s.",
241 jaylink_strerror(ret
));
245 ret
= transport_read(devh
, buf
, 4);
247 if (ret
!= JAYLINK_OK
) {
248 log_err(ctx
, "transport_read() failed: %s.",
249 jaylink_strerror(ret
));
254 *prev_iface
= buffer_get_u32(buf
, 0);
260 * Retrieve the available target interfaces.
262 * The target interfaces are stored in a 32-bit bit field where each individual
263 * bit represents a target interface. A set bit indicates an available target
264 * interface. See #jaylink_target_interface for a description of the target
265 * interfaces and their bit positions.
267 * @note This function must only be used if the device has the
268 * #JAYLINK_DEV_CAP_SELECT_TIF capability.
270 * @param[in,out] devh Device handle.
271 * @param[out] ifaces Target interfaces on success, and undefined on failure.
273 * @retval JAYLINK_OK Success.
274 * @retval JAYLINK_ERR_ARG Invalid arguments.
275 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
276 * @retval JAYLINK_ERR_IO Input/output error.
277 * @retval JAYLINK_ERR Other error conditions.
279 * @see jaylink_select_interface()
283 JAYLINK_API
int jaylink_get_available_interfaces(
284 struct jaylink_device_handle
*devh
, uint32_t *ifaces
)
287 struct jaylink_context
*ctx
;
290 if (!devh
|| !ifaces
)
291 return JAYLINK_ERR_ARG
;
293 ctx
= devh
->dev
->ctx
;
294 ret
= transport_start_write_read(devh
, 2, 4, true);
296 if (ret
!= JAYLINK_OK
) {
297 log_err(ctx
, "transport_start_write_read() failed: %s.",
298 jaylink_strerror(ret
));
302 buf
[0] = CMD_SELECT_TIF
;
303 buf
[1] = TIF_GET_AVAILABLE
;
305 ret
= transport_write(devh
, buf
, 2);
307 if (ret
!= JAYLINK_OK
) {
308 log_err(ctx
, "transport_write() failed: %s.",
309 jaylink_strerror(ret
));
313 ret
= transport_read(devh
, buf
, 4);
315 if (ret
!= JAYLINK_OK
) {
316 log_err(ctx
, "transport_read() failed: %s.",
317 jaylink_strerror(ret
));
321 *ifaces
= buffer_get_u32(buf
, 0);
327 * Retrieve the selected target interface.
329 * @note This function must only be used if the device has the
330 * #JAYLINK_DEV_CAP_SELECT_TIF capability.
332 * @warning This function may return a value for @p iface which is not covered
333 * by #jaylink_target_interface.
335 * @param[in,out] devh Device handle.
336 * @param[out] iface Selected target interface on success, and undefined on
339 * @retval JAYLINK_OK Success.
340 * @retval JAYLINK_ERR_ARG Invalid arguments.
341 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
342 * @retval JAYLINK_ERR_IO Input/output error.
343 * @retval JAYLINK_ERR Other error conditions.
345 * @see jaylink_select_interface()
349 JAYLINK_API
int jaylink_get_selected_interface(
350 struct jaylink_device_handle
*devh
,
351 enum jaylink_target_interface
*iface
)
354 struct jaylink_context
*ctx
;
358 return JAYLINK_ERR_ARG
;
360 ctx
= devh
->dev
->ctx
;
361 ret
= transport_start_write_read(devh
, 2, 4, true);
363 if (ret
!= JAYLINK_OK
) {
364 log_err(ctx
, "transport_start_write_read() failed: %s.",
365 jaylink_strerror(ret
));
369 buf
[0] = CMD_SELECT_TIF
;
370 buf
[1] = TIF_GET_SELECTED
;
372 ret
= transport_write(devh
, buf
, 2);
374 if (ret
!= JAYLINK_OK
) {
375 log_err(ctx
, "transport_write() failed: %s.",
376 jaylink_strerror(ret
));
380 ret
= transport_read(devh
, buf
, 4);
382 if (ret
!= JAYLINK_OK
) {
383 log_err(ctx
, "transport_read() failed: %s.",
384 jaylink_strerror(ret
));
388 *iface
= buffer_get_u32(buf
, 0);
394 * Clear the target reset signal.
396 * @param[in,out] devh Device handle.
398 * @retval JAYLINK_OK Success.
399 * @retval JAYLINK_ERR_ARG Invalid arguments.
400 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
401 * @retval JAYLINK_ERR_IO Input/output error.
402 * @retval JAYLINK_ERR Other error conditions.
406 JAYLINK_API
int jaylink_clear_reset(struct jaylink_device_handle
*devh
)
409 struct jaylink_context
*ctx
;
413 return JAYLINK_ERR_ARG
;
415 ctx
= devh
->dev
->ctx
;
416 ret
= transport_start_write(devh
, 1, true);
418 if (ret
!= JAYLINK_OK
) {
419 log_err(ctx
, "transport_start_write() failed: %s.",
420 jaylink_strerror(ret
));
424 buf
[0] = CMD_CLEAR_RESET
;
426 ret
= transport_write(devh
, buf
, 1);
428 if (ret
!= JAYLINK_OK
) {
429 log_err(ctx
, "transport_write() failed: %s.",
430 jaylink_strerror(ret
));
438 * Set the target reset signal.
440 * @param[in,out] devh Device handle.
442 * @retval JAYLINK_OK Success.
443 * @retval JAYLINK_ERR_ARG Invalid arguments.
444 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
445 * @retval JAYLINK_ERR_IO Input/output error.
446 * @retval JAYLINK_ERR Other error conditions.
450 JAYLINK_API
int jaylink_set_reset(struct jaylink_device_handle
*devh
)
453 struct jaylink_context
*ctx
;
457 return JAYLINK_ERR_ARG
;
459 ctx
= devh
->dev
->ctx
;
460 ret
= transport_start_write(devh
, 1, true);
462 if (ret
!= JAYLINK_OK
) {
463 log_err(ctx
, "transport_start_write() failed: %s.",
464 jaylink_strerror(ret
));
468 buf
[0] = CMD_SET_RESET
;
470 ret
= transport_write(devh
, buf
, 1);
472 if (ret
!= JAYLINK_OK
) {
473 log_err(ctx
, "transport_write() failed: %s.",
474 jaylink_strerror(ret
));
482 * Set the target power supply.
484 * If enabled, the target is supplied with 5 V from pin 19 of the 20-pin
485 * JTAG / SWD connector.
487 * @note This function must only be used if the device has the
488 * #JAYLINK_DEV_CAP_SET_TARGET_POWER capability.
490 * @param[in,out] devh Device handle.
491 * @param[in] enable Determines whether to enable or disable the target power
494 * @retval JAYLINK_OK Success.
495 * @retval JAYLINK_ERR_ARG Invalid arguments.
496 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
497 * @retval JAYLINK_ERR_IO Input/output error.
498 * @retval JAYLINK_ERR Other error conditions.
502 JAYLINK_API
int jaylink_set_target_power(struct jaylink_device_handle
*devh
,
506 struct jaylink_context
*ctx
;
510 return JAYLINK_ERR_ARG
;
512 ctx
= devh
->dev
->ctx
;
513 ret
= transport_start_write(devh
, 2, true);
515 if (ret
!= JAYLINK_OK
) {
516 log_err(ctx
, "transport_start_wrte() failed: %s.",
517 jaylink_strerror(ret
));
521 buf
[0] = CMD_SET_TARGET_POWER
;
524 ret
= transport_write(devh
, buf
, 2);
526 if (ret
!= JAYLINK_OK
) {
527 log_err(ctx
, "transport_write() failed: %s.",
528 jaylink_strerror(ret
));