OpenOCD
versaloon.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
5  ***************************************************************************/
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "versaloon_include.h"
12 
13 #include <stdio.h>
14 #include <string.h>
15 #include <libusb.h>
16 
17 #include "versaloon.h"
18 #include "versaloon_internal.h"
19 #include "usbtoxxx/usbtoxxx.h"
20 
21 uint8_t *versaloon_buf;
24 
27 
28 struct libusb_device_handle *versaloon_usb_device_handle;
30 
31 static RESULT versaloon_init(void);
32 static RESULT versaloon_fini(void);
33 static RESULT versaloon_get_target_voltage(uint16_t *voltage);
34 static RESULT versaloon_set_target_voltage(uint16_t voltage);
35 static RESULT versaloon_delay_ms(uint16_t ms);
36 static RESULT versaloon_delay_us(uint16_t us);
37 
40  .fini = versaloon_fini,
41  { /* adaptors */
42  { /* target_voltage */
45  },
46  { /* gpio */
47  .init = usbtogpio_init,
48  .fini = usbtogpio_fini,
49  .config = usbtogpio_config,
50  .out = usbtogpio_out,
51  .in = usbtogpio_in,
52  },
53  { /* delay */
54  .delayms = versaloon_delay_ms,
55  .delayus = versaloon_delay_us,
56  },
57  { /* swd */
58  .init = usbtoswd_init,
59  .fini = usbtoswd_fini,
60  .config = usbtoswd_config,
61  .seqout = usbtoswd_seqout,
62  .seqin = usbtoswd_seqin,
63  .transact = usbtoswd_transact,
64  },
65  { /* jtag_raw */
66  .init = usbtojtagraw_init,
67  .fini = usbtojtagraw_fini,
68  .config = usbtojtagraw_config,
69  .execute = usbtojtagraw_execute,
70  },
71  .peripheral_commit = usbtoxxx_execute_command,
72  },
73  { /* usb_setting */
74  .vid = VERSALOON_VID,
75  .pid = VERSALOON_PID,
76  .ep_out = VERSALOON_OUTP,
77  .ep_in = VERSALOON_INP,
78  .interface = VERSALOON_IFACE,
79  .buf_size = 256,
80  }
81 };
82 
83 /* programmer_cmd */
84 static uint32_t versaloon_pending_id;
86 static void *versaloon_extra_data;
88 
89 void versaloon_set_pending_id(uint32_t id)
90 {
92 }
94 {
95  versaloon_callback = callback;
96 }
98 {
100 }
101 
103 {
104  uint16_t i;
105  struct versaloon_want_pos_t *tmp, *free_tmp;
106 
107  tmp = versaloon_want_pos;
108  while (tmp) {
109  free_tmp = tmp;
110  tmp = tmp->next;
111  free(free_tmp);
112  }
114 
115  for (i = 0; i < ARRAY_SIZE(versaloon_pending); i++) {
116  tmp = versaloon_pending[i].pos;
117  while (tmp) {
118  free_tmp = tmp;
119  tmp = tmp->next;
120  free(free_tmp);
121  }
123  }
124 }
125 
126 RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff)
127 {
128  struct versaloon_want_pos_t *new_pos = NULL;
129 
130  new_pos = malloc(sizeof(*new_pos));
131  if (!new_pos) {
134  }
135  new_pos->offset = offset;
136  new_pos->size = size;
137  new_pos->buff = buff;
138  new_pos->next = NULL;
139 
140  if (!versaloon_want_pos)
141  versaloon_want_pos = new_pos;
142  else {
144 
145  while (tmp->next)
146  tmp = tmp->next;
147  tmp->next = new_pos;
148  }
149 
150  return ERROR_OK;
151 }
152 
153 RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie,
154  uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect)
155 {
156 #if PARAM_CHECK
159  "versaloon pending data");
160  return ERROR_FAIL;
161  }
162 #endif
163 
180 
181  return ERROR_OK;
182 }
183 
184 RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen)
185 {
186  int ret;
187  int transferred;
188 
189 #if PARAM_CHECK
190  if (!versaloon_buf) {
192  return ERRCODE_INVALID_BUFFER;
193  }
194  if ((out_len == 0) || (out_len > versaloon_interface.usb_setting.buf_size)) {
197  }
198 #endif
199 
200  ret = libusb_bulk_transfer(versaloon_usb_device_handle,
202  versaloon_buf, out_len, &transferred, versaloon_usb_to);
203  if (ret != 0 || transferred != out_len) {
204  LOG_ERROR(ERRMSG_FAILURE_OPERATION, "send usb data");
206  }
207 
208  if (inlen) {
209  ret = libusb_bulk_transfer(versaloon_usb_device_handle,
212  &transferred, versaloon_usb_to);
213  if (ret == 0) {
214  *inlen = (uint16_t)transferred;
215  return ERROR_OK;
216  } else {
217  LOG_ERROR(ERRMSG_FAILURE_OPERATION, "receive usb data");
218  return ERROR_FAIL;
219  }
220  } else
221  return ERROR_OK;
222 }
223 
224 #define VERSALOON_RETRY_CNT 10
225 static RESULT versaloon_init(void)
226 {
227  uint16_t ret = 0;
228  uint8_t retry;
229  uint32_t timeout_tmp;
230 
231  /* malloc temporary buffer */
233  if (!versaloon_buf) {
236  }
237 
238  /* connect to versaloon */
239  timeout_tmp = versaloon_usb_to;
240  /* not output error message when connecting */
241  /* 100ms delay when connect */
242  versaloon_usb_to = 100;
243  for (retry = 0; retry < VERSALOON_RETRY_CNT; retry++) {
245  if ((versaloon_send_command(1, &ret) == ERROR_OK) && (ret >= 3))
246  break;
247  }
248  versaloon_usb_to = timeout_tmp;
249  if (retry == VERSALOON_RETRY_CNT) {
250  versaloon_fini();
251  LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon");
253  }
254 
255  versaloon_buf[ret] = 0;
258  LOG_INFO("%s", versaloon_buf + 2);
259 
260  /* free temporary buffer */
261  free(versaloon_buf);
263 
265  if (!versaloon_buf) {
266  versaloon_fini();
269  }
271  if (!versaloon_cmd_buf) {
272  versaloon_fini();
275  }
276  if (usbtoxxx_init() != ERROR_OK) {
277  LOG_ERROR(ERRMSG_FAILURE_OPERATION, "initialize usbtoxxx");
278  return ERROR_FAIL;
279  }
280  return versaloon_get_target_voltage(&ret);
281 }
282 
283 static RESULT versaloon_fini(void)
284 {
286  usbtoxxx_fini();
288 
290 
291  free(versaloon_buf);
293 
294  free(versaloon_cmd_buf);
296  }
297 
298  return ERROR_OK;
299 }
300 
301 static RESULT versaloon_set_target_voltage(uint16_t voltage)
302 {
303  usbtopwr_init(0);
304  usbtopwr_config(0);
305  usbtopwr_output(0, voltage);
306  usbtopwr_fini(0);
307 
308  return usbtoxxx_execute_command();
309 }
310 
311 static RESULT versaloon_get_target_voltage(uint16_t *voltage)
312 {
313  uint16_t inlen;
314 
315 #if PARAM_CHECK
316  if (!versaloon_buf) {
318  return ERRCODE_INVALID_BUFFER;
319  }
320  if (!voltage) {
323  }
324 #endif
325 
327 
328  if ((versaloon_send_command(1, &inlen) != ERROR_OK) || (inlen != 2)) {
329  LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon");
331  } else {
332  *voltage = versaloon_buf[0] + (versaloon_buf[1] << 8);
333  return ERROR_OK;
334  }
335 }
336 
337 static RESULT versaloon_delay_ms(uint16_t ms)
338 {
339  return usbtodelay_delay(ms | 0x8000);
340 }
341 
342 static RESULT versaloon_delay_us(uint16_t us)
343 {
344  return usbtodelay_delay(us & 0x7FFF);
345 }
uint8_t type
Definition: esp_usb_jtag.c:0
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define ERROR_OK
Definition: log.h:155
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
char id[RTT_CB_MAX_ID_LENGTH]
Control block identifier.
Definition: rtt/rtt.c:32
RESULT(* init)(void)
Definition: versaloon.h:90
struct versaloon_usb_setting_t usb_setting
Definition: versaloon.h:93
struct versaloon_want_pos_t * pos
versaloon_callback_t callback
struct versaloon_want_pos_t * next
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
RESULT usbtogpio_init(uint8_t interface_index)
Definition: usbtogpio.c:19
RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask, uint32_t dir_mask, uint32_t pull_en_mask, uint32_t input_pull_mask)
Definition: usbtogpio.c:29
RESULT usbtogpio_fini(uint8_t interface_index)
Definition: usbtogpio.c:24
RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value)
Definition: usbtogpio.c:52
RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value)
Definition: usbtogpio.c:69
RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t khz)
Definition: usbtojtagraw.c:29
RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi, uint8_t *tms, uint8_t *tdo, uint32_t bitlen)
Definition: usbtojtagraw.c:45
RESULT usbtojtagraw_fini(uint8_t interface_index)
Definition: usbtojtagraw.c:24
RESULT usbtojtagraw_init(uint8_t interface_index)
Definition: usbtojtagraw.c:19
RESULT usbtopwr_init(uint8_t interface_index)
Definition: usbtopwr.c:19
RESULT usbtopwr_fini(uint8_t interface_index)
Definition: usbtopwr.c:24
RESULT usbtopwr_output(uint8_t interface_index, uint16_t millivolt)
Definition: usbtopwr.c:41
RESULT usbtopwr_config(uint8_t interface_index)
Definition: usbtopwr.c:29
RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen)
Definition: usbtoswd.c:90
RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request, uint32_t *data, uint8_t *ack)
Definition: usbtoswd.c:108
RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry, uint16_t dly)
Definition: usbtoswd.c:52
RESULT usbtoswd_init(uint8_t interface_index)
Definition: usbtoswd.c:42
RESULT usbtoswd_fini(uint8_t interface_index)
Definition: usbtoswd.c:47
RESULT usbtoswd_seqout(uint8_t interface_index, const uint8_t *data, uint16_t bitlen)
Definition: usbtoswd.c:71
RESULT usbtoxxx_init(void)
Definition: usbtoxxx.c:233
RESULT usbtodelay_delay(uint16_t dly)
Definition: usbtoxxx.c:517
RESULT usbtoxxx_execute_command(void)
Definition: usbtoxxx.c:106
RESULT usbtoxxx_fini(void)
Definition: usbtoxxx.c:247
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
static RESULT versaloon_init(void)
Definition: versaloon.c:225
void versaloon_set_callback(versaloon_callback_t callback)
Definition: versaloon.c:93
void versaloon_free_want_pos(void)
Definition: versaloon.c:102
void versaloon_set_pending_id(uint32_t id)
Definition: versaloon.c:89
static versaloon_callback_t versaloon_callback
Definition: versaloon.c:85
#define VERSALOON_RETRY_CNT
Definition: versaloon.c:224
uint8_t * versaloon_buf
Definition: versaloon.c:21
static RESULT versaloon_get_target_voltage(uint16_t *voltage)
Definition: versaloon.c:311
static RESULT versaloon_delay_us(uint16_t us)
Definition: versaloon.c:342
uint16_t versaloon_pending_idx
Definition: versaloon.c:26
void versaloon_set_extra_data(void *p)
Definition: versaloon.c:97
static struct versaloon_want_pos_t * versaloon_want_pos
Definition: versaloon.c:87
struct libusb_device_handle * versaloon_usb_device_handle
Definition: versaloon.c:28
struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]
Definition: versaloon.c:25
uint8_t * versaloon_cmd_buf
Definition: versaloon.c:22
static RESULT versaloon_delay_ms(uint16_t ms)
Definition: versaloon.c:337
static RESULT versaloon_fini(void)
Definition: versaloon.c:283
static uint32_t versaloon_usb_to
Definition: versaloon.c:29
static RESULT versaloon_set_target_voltage(uint16_t voltage)
Definition: versaloon.c:301
uint16_t versaloon_buf_size
Definition: versaloon.c:23
RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie, uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect)
Definition: versaloon.c:153
static uint32_t versaloon_pending_id
Definition: versaloon.c:84
RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen)
Definition: versaloon.c:184
RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff)
Definition: versaloon.c:126
static void * versaloon_extra_data
Definition: versaloon.c:86
struct versaloon_interface_t versaloon_interface
Definition: versaloon.c:38
#define ERRCODE_NOT_ENOUGH_MEMORY
#define ERRCODE_INVALID_BUFFER
#define ERRMSG_INVALID_PARAMETER
#define ERRMSG_INVALID_INDEX
#define ERRCODE_FAILURE_OPERATION
#define TO_STR(name)
#define RESULT
#define ERRMSG_NOT_ENOUGH_MEMORY
#define ERRCODE_INVALID_PARAMETER
#define LOG_BUG
#define ERRMSG_FAILURE_OPERATION
#define ERRMSG_INVALID_BUFFER
#define VERSALOON_OUTP
#define VERSALOON_GET_INFO
RESULT(* versaloon_callback_t)(void *, uint8_t *, uint8_t *)
#define VERSALOON_GET_TVCC
#define VERSALOON_IFACE
#define VERSALOON_TIMEOUT
#define VERSALOON_INP
#define VERSALOON_PID
#define VERSALOON_MAX_PENDING_NUMBER
#define VERSALOON_VID