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 * Serial Wire Debug (SWD) functions.
33 #define CMD_SWD_IO 0xcf
36 * Error code indicating that there is not enough free memory on the device to
37 * perform the SWD I/O operation.
39 #define SWD_IO_ERR_NO_MEMORY 0x06
43 * Perform a SWD I/O operation.
45 * @note This function must only be used if the #JAYLINK_TIF_SWD interface is
46 * available and selected.
48 * @param[in,out] devh Device handle.
49 * @param[in] direction Buffer to read the transfer direction from.
50 * @param[in] out Buffer to read host-to-target data from.
51 * @param[out] in Buffer to store target-to-host data on success. Its content is
52 * undefined on failure. The buffer must be large enough to
53 * contain at least the specified number of bits to transfer.
54 * @param[in] length Total number of bits to transfer from host to target and
57 * @retval JAYLINK_OK Success.
58 * @retval JAYLINK_ERR_ARG Invalid arguments.
59 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
60 * @retval JAYLINK_ERR_DEV Unspecified device error.
61 * @retval JAYLINK_ERR_DEV_NO_MEMORY Not enough memory on the device to perform
63 * @retval JAYLINK_ERR Other error conditions.
65 * @see jaylink_select_interface() to select the target interface.
66 * @see jaylink_get_available_interfaces() to retrieve the available target
71 JAYLINK_API
int jaylink_swd_io(struct jaylink_device_handle
*devh
,
72 const uint8_t *direction
, const uint8_t *out
, uint8_t *in
,
76 struct jaylink_context
*ctx
;
81 if (!devh
|| !direction
|| !out
|| !in
|| !length
)
82 return JAYLINK_ERR_ARG
;
85 num_bytes
= (length
+ 7) / 8;
87 ret
= transport_start_write_read(devh
, 4 + 2 * num_bytes
,
90 if (ret
!= JAYLINK_OK
) {
91 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
97 buffer_set_u16(buf
, length
, 2);
99 ret
= transport_write(devh
, buf
, 4);
101 if (ret
!= JAYLINK_OK
) {
102 log_err(ctx
, "transport_write() failed: %i.", ret
);
106 ret
= transport_write(devh
, direction
, num_bytes
);
108 if (ret
!= JAYLINK_OK
) {
109 log_err(ctx
, "transport_write() failed: %i.", ret
);
113 ret
= transport_write(devh
, out
, num_bytes
);
115 if (ret
!= JAYLINK_OK
) {
116 log_err(ctx
, "transport_write() failed: %i.", ret
);
120 ret
= transport_read(devh
, in
, num_bytes
);
122 if (ret
!= JAYLINK_OK
) {
123 log_err(ctx
, "transport_read() failed: %i.", ret
);
127 ret
= transport_read(devh
, &status
, 1);
129 if (ret
!= JAYLINK_OK
) {
130 log_err(ctx
, "transport_read() failed: %i.", ret
);
134 if (status
== SWD_IO_ERR_NO_MEMORY
) {
135 return JAYLINK_ERR_DEV_NO_MEMORY
;
136 } else if (status
> 0) {
137 log_err(ctx
, "SWD I/O operation failed: %02x.", status
);
138 return JAYLINK_ERR_DEV
;