Bump package version to 0.4.0
[libjaylink.git] / libjaylink / target.c
blob6715662f8a17d4bee5c1aafb4cefa5369afc049e
1 /*
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/>.
20 #include <stdint.h>
21 #include <stdbool.h>
23 #include "libjaylink.h"
24 #include "libjaylink-internal.h"
26 /**
27 * @file
29 * Target related functions.
32 /** @cond PRIVATE */
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
42 /** @endcond */
44 /**
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()
61 * @since 0.1.0
63 JAYLINK_API int jaylink_set_speed(struct jaylink_device_handle *devh,
64 uint16_t speed)
66 int ret;
67 struct jaylink_context *ctx;
68 uint8_t buf[3];
70 if (!devh || !speed)
71 return JAYLINK_ERR_ARG;
73 ctx = devh->dev->ctx;
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));
79 return 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));
90 return ret;
93 return JAYLINK_OK;
96 /**
97 * Retrieve target interface speeds.
99 * The speeds are applicable for the currently selected target interface only
100 * and calculated as follows:
102 * @par
103 * <tt>speeds = @a freq / n</tt> with <tt>n >= @a div</tt>, where @p n is an
104 * integer
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
109 * so on.
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()
126 * @since 0.1.0
128 JAYLINK_API int jaylink_get_speeds(struct jaylink_device_handle *devh,
129 struct jaylink_speed *speed)
131 int ret;
132 struct jaylink_context *ctx;
133 uint8_t buf[6];
134 uint16_t div;
136 if (!devh || !speed)
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));
145 return 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));
155 return 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));
163 return ret;
166 div = buffer_get_u16(buf, 4);
168 if (!div) {
169 log_err(ctx, "Minimum frequency divider is zero");
170 return JAYLINK_ERR_PROTO;
173 speed->freq = buffer_get_u32(buf, 0);
174 speed->div = div;
176 return JAYLINK_OK;
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()
201 * @since 0.1.0
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)
207 int ret;
208 struct jaylink_context *ctx;
209 uint8_t buf[4];
211 if (!devh)
212 return JAYLINK_ERR_ARG;
214 switch (iface) {
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:
220 case JAYLINK_TIF_SPI:
221 case JAYLINK_TIF_C2:
222 case JAYLINK_TIF_CJTAG:
223 break;
224 default:
225 return JAYLINK_ERR_ARG;
228 ctx = devh->dev->ctx;
229 ret = transport_start_write_read(devh, 2, 4, true);
231 if (ret != JAYLINK_OK) {
232 log_err(ctx, "transport_start_write_read() failed: %s",
233 jaylink_strerror(ret));
234 return ret;
237 buf[0] = CMD_SELECT_TIF;
238 buf[1] = iface;
240 ret = transport_write(devh, buf, 2);
242 if (ret != JAYLINK_OK) {
243 log_err(ctx, "transport_write() failed: %s",
244 jaylink_strerror(ret));
245 return ret;
248 ret = transport_read(devh, buf, 4);
250 if (ret != JAYLINK_OK) {
251 log_err(ctx, "transport_read() failed: %s",
252 jaylink_strerror(ret));
253 return ret;
256 if (prev_iface)
257 *prev_iface = buffer_get_u32(buf, 0);
259 return JAYLINK_OK;
263 * Retrieve the available target interfaces.
265 * The target interfaces are stored in a 32-bit bit field where each individual
266 * bit represents a target interface. A set bit indicates an available target
267 * interface. See #jaylink_target_interface for a description of the target
268 * interfaces and their bit positions.
270 * @note This function must only be used if the device has the
271 * #JAYLINK_DEV_CAP_SELECT_TIF capability.
273 * @param[in,out] devh Device handle.
274 * @param[out] ifaces Target interfaces on success, and undefined on failure.
276 * @retval JAYLINK_OK Success.
277 * @retval JAYLINK_ERR_ARG Invalid arguments.
278 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
279 * @retval JAYLINK_ERR_IO Input/output error.
280 * @retval JAYLINK_ERR Other error conditions.
282 * @see jaylink_select_interface()
284 * @since 0.1.0
286 JAYLINK_API int jaylink_get_available_interfaces(
287 struct jaylink_device_handle *devh, uint32_t *ifaces)
289 int ret;
290 struct jaylink_context *ctx;
291 uint8_t buf[4];
293 if (!devh || !ifaces)
294 return JAYLINK_ERR_ARG;
296 ctx = devh->dev->ctx;
297 ret = transport_start_write_read(devh, 2, 4, true);
299 if (ret != JAYLINK_OK) {
300 log_err(ctx, "transport_start_write_read() failed: %s",
301 jaylink_strerror(ret));
302 return ret;
305 buf[0] = CMD_SELECT_TIF;
306 buf[1] = TIF_GET_AVAILABLE;
308 ret = transport_write(devh, buf, 2);
310 if (ret != JAYLINK_OK) {
311 log_err(ctx, "transport_write() failed: %s",
312 jaylink_strerror(ret));
313 return ret;
316 ret = transport_read(devh, buf, 4);
318 if (ret != JAYLINK_OK) {
319 log_err(ctx, "transport_read() failed: %s",
320 jaylink_strerror(ret));
321 return ret;
324 *ifaces = buffer_get_u32(buf, 0);
326 return JAYLINK_OK;
330 * Retrieve the selected target interface.
332 * @note This function must only be used if the device has the
333 * #JAYLINK_DEV_CAP_SELECT_TIF capability.
335 * @warning This function may return a value for @p iface which is not covered
336 * by #jaylink_target_interface.
338 * @param[in,out] devh Device handle.
339 * @param[out] iface Selected target interface on success, and undefined on
340 * failure.
342 * @retval JAYLINK_OK Success.
343 * @retval JAYLINK_ERR_ARG Invalid arguments.
344 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
345 * @retval JAYLINK_ERR_IO Input/output error.
346 * @retval JAYLINK_ERR Other error conditions.
348 * @see jaylink_select_interface()
350 * @since 0.1.0
352 JAYLINK_API int jaylink_get_selected_interface(
353 struct jaylink_device_handle *devh,
354 enum jaylink_target_interface *iface)
356 int ret;
357 struct jaylink_context *ctx;
358 uint8_t buf[4];
360 if (!devh || !iface)
361 return JAYLINK_ERR_ARG;
363 ctx = devh->dev->ctx;
364 ret = transport_start_write_read(devh, 2, 4, true);
366 if (ret != JAYLINK_OK) {
367 log_err(ctx, "transport_start_write_read() failed: %s",
368 jaylink_strerror(ret));
369 return ret;
372 buf[0] = CMD_SELECT_TIF;
373 buf[1] = TIF_GET_SELECTED;
375 ret = transport_write(devh, buf, 2);
377 if (ret != JAYLINK_OK) {
378 log_err(ctx, "transport_write() failed: %s",
379 jaylink_strerror(ret));
380 return ret;
383 ret = transport_read(devh, buf, 4);
385 if (ret != JAYLINK_OK) {
386 log_err(ctx, "transport_read() failed: %s",
387 jaylink_strerror(ret));
388 return ret;
391 *iface = buffer_get_u32(buf, 0);
393 return JAYLINK_OK;
397 * Clear the target reset signal.
399 * @param[in,out] devh Device handle.
401 * @retval JAYLINK_OK Success.
402 * @retval JAYLINK_ERR_ARG Invalid arguments.
403 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
404 * @retval JAYLINK_ERR_IO Input/output error.
405 * @retval JAYLINK_ERR Other error conditions.
407 * @since 0.1.0
409 JAYLINK_API int jaylink_clear_reset(struct jaylink_device_handle *devh)
411 int ret;
412 struct jaylink_context *ctx;
413 uint8_t buf[1];
415 if (!devh)
416 return JAYLINK_ERR_ARG;
418 ctx = devh->dev->ctx;
419 ret = transport_start_write(devh, 1, true);
421 if (ret != JAYLINK_OK) {
422 log_err(ctx, "transport_start_write() failed: %s",
423 jaylink_strerror(ret));
424 return ret;
427 buf[0] = CMD_CLEAR_RESET;
429 ret = transport_write(devh, buf, 1);
431 if (ret != JAYLINK_OK) {
432 log_err(ctx, "transport_write() failed: %s",
433 jaylink_strerror(ret));
434 return ret;
437 return JAYLINK_OK;
441 * Set the target reset signal.
443 * @param[in,out] devh Device handle.
445 * @retval JAYLINK_OK Success.
446 * @retval JAYLINK_ERR_ARG Invalid arguments.
447 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
448 * @retval JAYLINK_ERR_IO Input/output error.
449 * @retval JAYLINK_ERR Other error conditions.
451 * @since 0.1.0
453 JAYLINK_API int jaylink_set_reset(struct jaylink_device_handle *devh)
455 int ret;
456 struct jaylink_context *ctx;
457 uint8_t buf[1];
459 if (!devh)
460 return JAYLINK_ERR_ARG;
462 ctx = devh->dev->ctx;
463 ret = transport_start_write(devh, 1, true);
465 if (ret != JAYLINK_OK) {
466 log_err(ctx, "transport_start_write() failed: %s",
467 jaylink_strerror(ret));
468 return ret;
471 buf[0] = CMD_SET_RESET;
473 ret = transport_write(devh, buf, 1);
475 if (ret != JAYLINK_OK) {
476 log_err(ctx, "transport_write() failed: %s",
477 jaylink_strerror(ret));
478 return ret;
481 return JAYLINK_OK;
485 * Set the target power supply.
487 * If enabled, the target is supplied with 5 V from pin 19 of the 20-pin
488 * JTAG / SWD connector.
490 * @note This function must only be used if the device has the
491 * #JAYLINK_DEV_CAP_SET_TARGET_POWER capability.
493 * @param[in,out] devh Device handle.
494 * @param[in] enable Determines whether to enable or disable the target power
495 * supply.
497 * @retval JAYLINK_OK Success.
498 * @retval JAYLINK_ERR_ARG Invalid arguments.
499 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
500 * @retval JAYLINK_ERR_IO Input/output error.
501 * @retval JAYLINK_ERR Other error conditions.
503 * @since 0.1.0
505 JAYLINK_API int jaylink_set_target_power(struct jaylink_device_handle *devh,
506 bool enable)
508 int ret;
509 struct jaylink_context *ctx;
510 uint8_t buf[2];
512 if (!devh)
513 return JAYLINK_ERR_ARG;
515 ctx = devh->dev->ctx;
516 ret = transport_start_write(devh, 2, true);
518 if (ret != JAYLINK_OK) {
519 log_err(ctx, "transport_start_wrte() failed: %s",
520 jaylink_strerror(ret));
521 return ret;
524 buf[0] = CMD_SET_TARGET_POWER;
525 buf[1] = enable;
527 ret = transport_write(devh, buf, 2);
529 if (ret != JAYLINK_OK) {
530 log_err(ctx, "transport_write() failed: %s",
531 jaylink_strerror(ret));
532 return ret;
535 return JAYLINK_OK;