Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>tags/v0.6.0-rc1
@@ -67,6 +67,12 @@ DRIVERFILES += ulink.c | |||||
nobase_dist_pkglib_DATA += $(ULINK_FIRMWARE)/ulink_firmware.hex | nobase_dist_pkglib_DATA += $(ULINK_FIRMWARE)/ulink_firmware.hex | ||||
endif | endif | ||||
if VSLLINK | if VSLLINK | ||||
DRIVERFILES += versaloon/usbtoxxx/usbtogpio.c | |||||
DRIVERFILES += versaloon/usbtoxxx/usbtojtagraw.c | |||||
DRIVERFILES += versaloon/usbtoxxx/usbtoswd.c | |||||
DRIVERFILES += versaloon/usbtoxxx/usbtopwr.c | |||||
DRIVERFILES += versaloon/usbtoxxx/usbtoxxx.c | |||||
DRIVERFILES += versaloon/versaloon.c | |||||
DRIVERFILES += vsllink.c | DRIVERFILES += vsllink.c | ||||
endif | endif | ||||
if ARMJTAGEW | if ARMJTAGEW | ||||
@@ -0,0 +1,100 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <string.h> | |||||
#include "../versaloon_include.h" | |||||
#include "../versaloon.h" | |||||
#include "../versaloon_internal.h" | |||||
#include "usbtoxxx.h" | |||||
#include "usbtoxxx_internal.h" | |||||
RESULT usbtogpio_init(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_init_command(USB_TO_GPIO, interface_index); | |||||
} | |||||
RESULT usbtogpio_fini(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_fini_command(USB_TO_GPIO, interface_index); | |||||
} | |||||
RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask, | |||||
uint32_t dir_mask, uint32_t pull_en_mask, | |||||
uint32_t input_pull_mask) | |||||
{ | |||||
uint8_t conf[8]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
dir_mask &= mask; | |||||
SET_LE_U16(&conf[0], mask); | |||||
SET_LE_U16(&conf[2], dir_mask); | |||||
SET_LE_U16(&conf[4], pull_en_mask); | |||||
SET_LE_U16(&conf[6], input_pull_mask); | |||||
return usbtoxxx_conf_command(USB_TO_GPIO, interface_index, conf, | |||||
sizeof(conf)); | |||||
} | |||||
RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value) | |||||
{ | |||||
uint8_t buf[2]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
SET_LE_U16(&buf[0], mask); | |||||
return usbtoxxx_in_command(USB_TO_GPIO, interface_index, buf, 2, 2, | |||||
(uint8_t*)value, 0, 2, 0); | |||||
} | |||||
RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value) | |||||
{ | |||||
uint8_t buf[4]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
SET_LE_U16(&buf[0], mask); | |||||
SET_LE_U16(&buf[2], value); | |||||
return usbtoxxx_out_command(USB_TO_GPIO, interface_index, buf, 4, 0); | |||||
} | |||||
@@ -0,0 +1,84 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <string.h> | |||||
#include "../versaloon_include.h" | |||||
#include "../versaloon.h" | |||||
#include "../versaloon_internal.h" | |||||
#include "usbtoxxx.h" | |||||
#include "usbtoxxx_internal.h" | |||||
RESULT usbtojtagraw_init(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_init_command(USB_TO_JTAG_RAW, interface_index); | |||||
} | |||||
RESULT usbtojtagraw_fini(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_fini_command(USB_TO_JTAG_RAW, interface_index); | |||||
} | |||||
RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz) | |||||
{ | |||||
uint8_t cfg_buf[4]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
SET_LE_U32(&cfg_buf[0], kHz); | |||||
return usbtoxxx_conf_command(USB_TO_JTAG_RAW, interface_index, cfg_buf, 4); | |||||
} | |||||
RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi, | |||||
uint8_t *tms, uint8_t *tdo, uint32_t bitlen) | |||||
{ | |||||
uint16_t bytelen; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
if (bitlen > 8 * 0xFFFF) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
bytelen = (uint16_t)((bitlen + 7) >> 3); | |||||
SET_LE_U32(&versaloon_cmd_buf[0], bitlen); | |||||
memcpy(versaloon_cmd_buf + 4, tdi, bytelen); | |||||
memcpy(versaloon_cmd_buf + 4 + bytelen, tms, bytelen); | |||||
return usbtoxxx_inout_command(USB_TO_JTAG_RAW, interface_index, | |||||
versaloon_cmd_buf, 4 + bytelen * 2, bytelen, tdo, 0, bytelen, 0); | |||||
} | |||||
@@ -0,0 +1,67 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <string.h> | |||||
#include "../versaloon_include.h" | |||||
#include "../versaloon.h" | |||||
#include "../versaloon_internal.h" | |||||
#include "usbtoxxx.h" | |||||
#include "usbtoxxx_internal.h" | |||||
RESULT usbtopwr_init(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_init_command(USB_TO_POWER, interface_index); | |||||
} | |||||
RESULT usbtopwr_fini(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_fini_command(USB_TO_POWER, interface_index); | |||||
} | |||||
RESULT usbtopwr_config(uint8_t interface_index) | |||||
{ | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
return usbtoxxx_conf_command(USB_TO_POWER, interface_index, NULL, 0); | |||||
} | |||||
RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV) | |||||
{ | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
return usbtoxxx_out_command(USB_TO_POWER, interface_index, (uint8_t *)&mV, | |||||
2, 0); | |||||
} | |||||
@@ -0,0 +1,158 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include "../versaloon_include.h" | |||||
#include "../versaloon.h" | |||||
#include "../versaloon_internal.h" | |||||
#include "usbtoxxx.h" | |||||
#include "usbtoxxx_internal.h" | |||||
RESULT usbtoswd_callback(void *p, uint8_t *src, uint8_t *processed) | |||||
{ | |||||
struct versaloon_pending_t *pending = (struct versaloon_pending_t *)p; | |||||
processed = processed; | |||||
if (pending->extra_data != NULL) | |||||
{ | |||||
*((uint8_t *)pending->extra_data) = src[0]; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtoswd_init(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_init_command(USB_TO_SWD, interface_index); | |||||
} | |||||
RESULT usbtoswd_fini(uint8_t interface_index) | |||||
{ | |||||
return usbtoxxx_fini_command(USB_TO_SWD, interface_index); | |||||
} | |||||
RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry, | |||||
uint16_t dly) | |||||
{ | |||||
uint8_t cfg_buf[5]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
cfg_buf[0] = trn; | |||||
SET_LE_U16(&cfg_buf[1], retry); | |||||
SET_LE_U16(&cfg_buf[3], dly); | |||||
return usbtoxxx_conf_command(USB_TO_SWD, interface_index, cfg_buf, 5); | |||||
} | |||||
RESULT usbtoswd_seqout(uint8_t interface_index, uint8_t *data, uint16_t bitlen) | |||||
{ | |||||
uint16_t bytelen = (bitlen + 7) >> 3; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
SET_LE_U16(&versaloon_cmd_buf[0], bitlen); | |||||
memcpy(versaloon_cmd_buf + 2, data, bytelen); | |||||
return usbtoxxx_out_command(USB_TO_SWD, interface_index, | |||||
versaloon_cmd_buf, bytelen + 2, 0); | |||||
} | |||||
RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen) | |||||
{ | |||||
uint16_t bytelen = (bitlen + 7) >> 3; | |||||
uint8_t buff[2]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
SET_LE_U16(&buff[0], bitlen); | |||||
return usbtoxxx_in_command(USB_TO_SWD, interface_index, buff, 2, bytelen, | |||||
data, 0, bytelen, 0); | |||||
} | |||||
RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request, | |||||
uint32_t *data, uint8_t *ack) | |||||
{ | |||||
uint8_t parity; | |||||
uint8_t buff[5]; | |||||
#if PARAM_CHECK | |||||
if (interface_index > 7) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
parity = (request >> 1) & 1; | |||||
parity += (request >> 2) & 1; | |||||
parity += (request >> 3) & 1; | |||||
parity += (request >> 4) & 1; | |||||
parity &= 1; | |||||
buff[0] = (request | 0x81 | (parity << 5)) & ~0x40; | |||||
if (data != NULL) | |||||
{ | |||||
SET_LE_U32(&buff[1], *data); | |||||
} | |||||
else | |||||
{ | |||||
memset(buff + 1, 0, 4); | |||||
} | |||||
versaloon_set_extra_data(ack); | |||||
versaloon_set_callback(usbtoswd_callback); | |||||
if (request & 0x04) | |||||
{ | |||||
// read | |||||
return usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5, | |||||
(uint8_t *)data, 1, 4, 0); | |||||
} | |||||
else | |||||
{ | |||||
// write | |||||
return usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5, | |||||
NULL, 0, 0, 0); | |||||
} | |||||
} | |||||
@@ -0,0 +1,652 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <string.h> | |||||
#include "../versaloon_include.h" | |||||
#include "../versaloon.h" | |||||
#include "../versaloon_internal.h" | |||||
#include "usbtoxxx.h" | |||||
#include "usbtoxxx_internal.h" | |||||
#define N_A "n/a" | |||||
const char* types_name[96] = | |||||
{ | |||||
"usbtousart", "usbtospi", "usbtoi2c", "usbtogpio", "usbtocan", "usbtopwm", | |||||
"usbtoadc", "usbtodac", | |||||
"usbtomicrowire", "usbtoswim", "usbtodusi", N_A, N_A, N_A, "usbtopower", "usbtodelay", | |||||
N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, | |||||
N_A, N_A, N_A, N_A, N_A, N_A, N_A, | |||||
"usbtojtagll", "usbtojtaghl", "usbtoissp", "usbtoc2", "usbtosbw", | |||||
"usbtolpcicp", "usbtoswd", "usbtojtagraw", | |||||
"usbtobdm", N_A, N_A, N_A, N_A, N_A, N_A, N_A, | |||||
N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, | |||||
"usbtomsp430jtag", N_A, N_A, N_A, N_A, N_A, N_A, N_A, | |||||
"usbtopower", "usbtodelay", "usbtopoll", N_A, N_A, N_A, N_A, N_A, | |||||
N_A, N_A, N_A, N_A, N_A, N_A, N_A, "usbtoall" | |||||
}; | |||||
uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN]; | |||||
#define usbtoxxx_get_type_name(type) \ | |||||
types_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \ | |||||
% (sizeof(types_name) / sizeof(types_name[0]))] | |||||
static uint8_t type_pre = 0; | |||||
static uint16_t usbtoxxx_buffer_index = 0; | |||||
static uint16_t usbtoxxx_current_cmd_index = 0; | |||||
static uint8_t *usbtoxxx_buffer = NULL; | |||||
uint16_t collect_index = 0; | |||||
uint8_t collect_cmd; | |||||
static uint8_t poll_nesting = 0; | |||||
struct usbtoxxx_context_t | |||||
{ | |||||
uint8_t type_pre; | |||||
uint8_t *usbtoxxx_buffer; | |||||
uint16_t usbtoxxx_current_cmd_index; | |||||
uint16_t usbtoxxx_buffer_index; | |||||
uint16_t versaloon_pending_idx; | |||||
}; | |||||
static struct usbtoxxx_context_t poll_context; | |||||
static void usbtoxxx_save_context(struct usbtoxxx_context_t *c) | |||||
{ | |||||
c->type_pre = type_pre; | |||||
c->usbtoxxx_buffer = usbtoxxx_buffer; | |||||
c->usbtoxxx_buffer_index = usbtoxxx_buffer_index; | |||||
c->usbtoxxx_current_cmd_index = usbtoxxx_current_cmd_index; | |||||
c->versaloon_pending_idx = versaloon_pending_idx; | |||||
} | |||||
static void usbtoxxx_pop_context(struct usbtoxxx_context_t *c) | |||||
{ | |||||
type_pre = c->type_pre; | |||||
usbtoxxx_buffer = c->usbtoxxx_buffer; | |||||
usbtoxxx_buffer_index = c->usbtoxxx_buffer_index; | |||||
usbtoxxx_current_cmd_index = c->usbtoxxx_current_cmd_index; | |||||
versaloon_pending_idx = c->versaloon_pending_idx; | |||||
} | |||||
RESULT usbtoxxx_validate_current_command_type(void) | |||||
{ | |||||
if (type_pre > 0) | |||||
{ | |||||
// not the first command | |||||
if (NULL == usbtoxxx_buffer) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(usbtoxxx_buffer)); | |||||
return ERRCODE_INVALID_BUFFER; | |||||
} | |||||
usbtoxxx_buffer[0] = type_pre; | |||||
SET_LE_U16(&usbtoxxx_buffer[1], usbtoxxx_current_cmd_index); | |||||
usbtoxxx_buffer_index += usbtoxxx_current_cmd_index; | |||||
} | |||||
else | |||||
{ | |||||
// first command | |||||
usbtoxxx_buffer_index = 3; | |||||
} | |||||
// prepare for next command | |||||
usbtoxxx_current_cmd_index = 3; | |||||
usbtoxxx_buffer = versaloon_buf + usbtoxxx_buffer_index; | |||||
collect_index = 0; | |||||
collect_cmd = 0; | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtoxxx_execute_command(void) | |||||
{ | |||||
uint16_t i; | |||||
uint16_t inlen; | |||||
RESULT result = ERROR_OK; | |||||
if (poll_nesting) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_USAGE, "USB_TO_POLL"); | |||||
versaloon_free_want_pos(); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
versaloon_free_want_pos(); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (3 == usbtoxxx_buffer_index) | |||||
{ | |||||
versaloon_free_want_pos(); | |||||
return ERROR_OK; | |||||
} | |||||
versaloon_buf[0] = USB_TO_ALL; | |||||
SET_LE_U16(&versaloon_buf[1], usbtoxxx_buffer_index); | |||||
if (ERROR_OK != versaloon_send_command(usbtoxxx_buffer_index, &inlen)) | |||||
{ | |||||
versaloon_free_want_pos(); | |||||
return ERROR_FAIL; | |||||
} | |||||
// process return data | |||||
usbtoxxx_buffer_index = 0; | |||||
for (i = 0; i < versaloon_pending_idx; i++) | |||||
{ | |||||
// check result | |||||
if ((0 == i) || !((versaloon_pending[i].collect) | |||||
&& (versaloon_pending[i - 1].collect) | |||||
&& (versaloon_pending[i].cmd | |||||
== versaloon_pending[i - 1].cmd))) | |||||
{ | |||||
if (USB_TO_XXX_CMD_NOT_SUPPORT | |||||
== versaloon_buf[usbtoxxx_buffer_index]) | |||||
{ | |||||
LOG_ERROR(ERRMSG_NOT_SUPPORT_BY, | |||||
usbtoxxx_get_type_name(versaloon_pending[i].type), | |||||
"current dongle"); | |||||
result = ERROR_FAIL; | |||||
break; | |||||
} | |||||
else if (USB_TO_XXX_OK != versaloon_buf[usbtoxxx_buffer_index]) | |||||
{ | |||||
LOG_ERROR("%s command 0x%02x failed with 0x%02x", | |||||
usbtoxxx_get_type_name(versaloon_pending[i].type), | |||||
versaloon_pending[i].cmd, | |||||
versaloon_buf[usbtoxxx_buffer_index]); | |||||
result = ERROR_FAIL; | |||||
break; | |||||
} | |||||
usbtoxxx_buffer_index++; | |||||
} | |||||
// get result data | |||||
if (versaloon_pending[i].pos != NULL) | |||||
{ | |||||
uint8_t processed = 0; | |||||
if (versaloon_pending[i].callback != NULL) | |||||
{ | |||||
versaloon_pending[i].callback(&versaloon_pending[i], | |||||
versaloon_buf + usbtoxxx_buffer_index, &processed); | |||||
} | |||||
if (!processed) | |||||
{ | |||||
struct versaloon_want_pos_t *tmp, *free_tmp; | |||||
free_tmp = tmp = versaloon_pending[i].pos; | |||||
while (tmp != NULL) | |||||
{ | |||||
if ((tmp->buff != NULL) && (tmp->size > 0)) | |||||
{ | |||||
memcpy(tmp->buff, versaloon_buf + usbtoxxx_buffer_index | |||||
+ tmp->offset, tmp->size); | |||||
} | |||||
free_tmp = tmp; | |||||
tmp = tmp->next; | |||||
free(free_tmp); | |||||
} | |||||
versaloon_pending[i].pos = NULL; | |||||
} | |||||
} | |||||
else if ((versaloon_pending[i].want_data_size > 0) | |||||
&& (versaloon_pending[i].data_buffer != NULL)) | |||||
{ | |||||
uint8_t processed = 0; | |||||
if (versaloon_pending[i].callback != NULL) | |||||
{ | |||||
versaloon_pending[i].callback(&versaloon_pending[i], | |||||
versaloon_buf + usbtoxxx_buffer_index, &processed); | |||||
} | |||||
if (!processed) | |||||
{ | |||||
memcpy(versaloon_pending[i].data_buffer, | |||||
versaloon_buf + usbtoxxx_buffer_index | |||||
+ versaloon_pending[i].want_data_pos, | |||||
versaloon_pending[i].want_data_size); | |||||
} | |||||
} | |||||
usbtoxxx_buffer_index += versaloon_pending[i].actual_data_size; | |||||
if (usbtoxxx_buffer_index > inlen) | |||||
{ | |||||
LOG_BUG("%s command 0x%02x process error", | |||||
usbtoxxx_get_type_name(versaloon_pending[i].type), | |||||
versaloon_pending[i].cmd); | |||||
result = ERROR_FAIL; | |||||
break; | |||||
} | |||||
} | |||||
// data is not the right size | |||||
if (inlen != usbtoxxx_buffer_index) | |||||
{ | |||||
LOG_ERROR(ERRMSG_INVALID_TARGET, "length of return data"); | |||||
result = ERROR_FAIL; | |||||
} | |||||
if (versaloon_pending_idx > 0) | |||||
{ | |||||
versaloon_pending_idx = 0; | |||||
} | |||||
else | |||||
{ | |||||
// no receive data, avoid collision | |||||
sleep_ms(10); | |||||
} | |||||
type_pre = 0; | |||||
collect_cmd = 0; | |||||
collect_index = 0; | |||||
versaloon_free_want_pos(); | |||||
return result; | |||||
} | |||||
RESULT usbtoxxx_init(void) | |||||
{ | |||||
versaloon_pending_idx = 0; | |||||
if ((ERROR_OK != usbtoinfo_get_abilities(usbtoxxx_abilities)) || | |||||
(ERROR_OK != usbtoxxx_execute_command())) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
LOG_INFO("USB_TO_XXX abilities: 0x%08X:0x%08X:0x%08X", | |||||
GET_LE_U32(&usbtoxxx_abilities[0]), | |||||
GET_LE_U32(&usbtoxxx_abilities[4]), | |||||
GET_LE_U32(&usbtoxxx_abilities[8])); | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtoxxx_fini(void) | |||||
{ | |||||
usbtoxxx_buffer = NULL; | |||||
type_pre = 0; | |||||
return ERROR_OK; | |||||
} | |||||
bool usbtoxxx_interface_supported(uint8_t cmd) | |||||
{ | |||||
if ((cmd < VERSALOON_USB_TO_XXX_CMD_START) || | |||||
(cmd > VERSALOON_USB_TO_XXX_CMD_END)) | |||||
{ | |||||
return false; | |||||
} | |||||
cmd -= VERSALOON_USB_TO_XXX_CMD_START; | |||||
return (usbtoxxx_abilities[cmd / 8] & (1 << (cmd % 8))) > 0; | |||||
} | |||||
RESULT usbtoxxx_ensure_buffer_size(uint16_t cmdlen) | |||||
{ | |||||
// check free space, commit if not enough | |||||
if (((usbtoxxx_buffer_index + usbtoxxx_current_cmd_index + cmdlen) | |||||
>= versaloon_buf_size) | |||||
|| (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER)) | |||||
{ | |||||
struct usbtoxxx_context_t context_tmp; | |||||
uint8_t poll_nesting_tmp = 0; | |||||
memset(&context_tmp, 0, sizeof(context_tmp)); | |||||
if (poll_nesting) | |||||
{ | |||||
if (0 == poll_context.type_pre) | |||||
{ | |||||
LOG_BUG("USB_TO_POLL toooooo long"); | |||||
return ERROR_OK; | |||||
} | |||||
usbtoxxx_save_context(&context_tmp); | |||||
usbtoxxx_pop_context(&poll_context); | |||||
poll_nesting_tmp = poll_nesting; | |||||
poll_nesting = 0; | |||||
} | |||||
if (usbtoxxx_execute_command() != ERROR_OK) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (poll_nesting_tmp) | |||||
{ | |||||
uint16_t newlen, oldlen; | |||||
newlen = context_tmp.versaloon_pending_idx | |||||
- poll_context.versaloon_pending_idx; | |||||
memcpy(&versaloon_pending[0], | |||||
&versaloon_pending[poll_context.versaloon_pending_idx], | |||||
sizeof(versaloon_pending[0]) * newlen); | |||||
context_tmp.versaloon_pending_idx = newlen; | |||||
oldlen = poll_context.usbtoxxx_buffer_index | |||||
+ poll_context.usbtoxxx_current_cmd_index; | |||||
newlen = context_tmp.usbtoxxx_buffer_index | |||||
+ context_tmp.usbtoxxx_current_cmd_index; | |||||
memcpy(versaloon_buf + 3, versaloon_buf + oldlen, newlen - oldlen); | |||||
oldlen -= 3; | |||||
context_tmp.usbtoxxx_buffer -= oldlen; | |||||
context_tmp.usbtoxxx_buffer_index -= oldlen; | |||||
usbtoxxx_pop_context(&context_tmp); | |||||
poll_nesting = poll_nesting_tmp; | |||||
} | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf, | |||||
uint16_t cmdlen, uint16_t retlen, uint8_t *wantbuf, | |||||
uint16_t wantpos, uint16_t wantlen, uint8_t collect) | |||||
{ | |||||
uint16_t len_tmp; | |||||
// 3 more bytes by usbtoxxx_validate_current_command_type | |||||
// 3 more bytes when ((0 == collect_index) || (collect_cmd != cmd)) | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(cmdlen + 6)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if ((type_pre != type) || (NULL == usbtoxxx_buffer)) | |||||
{ | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = type; | |||||
} | |||||
if ((0 == collect_index) || (collect_cmd != cmd)) | |||||
{ | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = cmd; | |||||
if (collect) | |||||
{ | |||||
collect_index = usbtoxxx_current_cmd_index; | |||||
collect_cmd = cmd; | |||||
} | |||||
else | |||||
{ | |||||
collect_index = 0; | |||||
collect_cmd = 0; | |||||
} | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], cmdlen); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
} | |||||
else | |||||
{ | |||||
len_tmp = GET_LE_U16(&usbtoxxx_buffer[collect_index]) + cmdlen; | |||||
SET_LE_U16(&usbtoxxx_buffer[collect_index], len_tmp); | |||||
} | |||||
if (cmdbuf != NULL) | |||||
{ | |||||
memcpy(usbtoxxx_buffer + usbtoxxx_current_cmd_index, cmdbuf, cmdlen); | |||||
usbtoxxx_current_cmd_index += cmdlen; | |||||
} | |||||
return versaloon_add_pending(type, cmd, retlen, wantpos, wantlen, | |||||
wantbuf, collect); | |||||
} | |||||
RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]) | |||||
{ | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = USB_TO_INFO; | |||||
return versaloon_add_pending(USB_TO_INFO, 0, USB_TO_XXX_ABILITIES_LEN, 0, | |||||
USB_TO_XXX_ABILITIES_LEN, abilities, 0); | |||||
} | |||||
RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us) | |||||
{ | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (!poll_nesting) | |||||
{ | |||||
usbtoxxx_save_context(&poll_context); | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
poll_nesting++; | |||||
type_pre = USB_TO_POLL; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_START; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], retry_cnt); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], interval_us); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0); | |||||
} | |||||
RESULT usbtopoll_end(void) | |||||
{ | |||||
if (!poll_nesting) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 1)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
poll_nesting--; | |||||
type_pre = USB_TO_POLL; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_END; | |||||
return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0); | |||||
} | |||||
RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size, | |||||
uint32_t mask, uint32_t value) | |||||
{ | |||||
uint8_t i; | |||||
if (size > 4) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__); | |||||
return ERRCODE_INVALID_PARAMETER; | |||||
} | |||||
if (!poll_nesting) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = USB_TO_POLL; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKOK; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ; | |||||
for (i =0; i < size; i++) | |||||
{ | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF; | |||||
} | |||||
for (i =0; i < size; i++) | |||||
{ | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size, | |||||
uint32_t mask, uint32_t value) | |||||
{ | |||||
uint8_t i; | |||||
if (size > 4) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__); | |||||
return ERRCODE_INVALID_PARAMETER; | |||||
} | |||||
if (!poll_nesting) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = USB_TO_POLL; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKFAIL; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ; | |||||
for (i =0; i < size; i++) | |||||
{ | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF; | |||||
} | |||||
for (i =0; i < size; i++) | |||||
{ | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff) | |||||
{ | |||||
if (!poll_nesting) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5 + size)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = USB_TO_POLL; | |||||
usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_VERIFYBUFF; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], size); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
memcpy(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], buff, size); | |||||
usbtoxxx_current_cmd_index += size; | |||||
return ERROR_OK; | |||||
} | |||||
RESULT usbtodelay_delay(uint16_t dly) | |||||
{ | |||||
if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 2)) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_validate_current_command_type()) | |||||
{ | |||||
LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
type_pre = USB_TO_DELAY; | |||||
SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], dly); | |||||
usbtoxxx_current_cmd_index += 2; | |||||
return versaloon_add_pending(USB_TO_DELAY, 0, 0, 0, 0, NULL, 0); | |||||
} | |||||
RESULT usbtodelay_delayms(uint16_t ms) | |||||
{ | |||||
return usbtodelay_delay(ms | 0x8000); | |||||
} | |||||
RESULT usbtodelay_delayus(uint16_t us) | |||||
{ | |||||
return usbtodelay_delay(us & 0x7FFF); | |||||
} | |||||
@@ -0,0 +1,278 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifndef __USBTOXXX_H_INCLUDED__ | |||||
#define __USBTOXXX_H_INCLUDED__ | |||||
RESULT usbtoxxx_init(void); | |||||
RESULT usbtoxxx_fini(void); | |||||
RESULT usbtoxxx_execute_command(void); | |||||
#define USB_TO_XXX_ABILITIES_LEN 12 | |||||
extern uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN]; | |||||
bool usbtoxxx_interface_supported(uint8_t cmd); | |||||
// USB_TO_INFO | |||||
RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]); | |||||
// USB_TO_DELAY | |||||
RESULT usbtodelay_delay(uint16_t dly); | |||||
RESULT usbtodelay_delayms(uint16_t ms); | |||||
RESULT usbtodelay_delayus(uint16_t us); | |||||
// USB_TO_USART | |||||
RESULT usbtousart_init(uint8_t interface_index); | |||||
RESULT usbtousart_fini(uint8_t interface_index); | |||||
RESULT usbtousart_config(uint8_t interface_index, uint32_t baudrate, | |||||
uint8_t datalength, uint8_t mode); | |||||
RESULT usbtousart_send(uint8_t interface_index, uint8_t *buf, uint16_t len); | |||||
RESULT usbtousart_receive(uint8_t interface_index, uint8_t *buf, uint16_t len); | |||||
RESULT usbtousart_status(uint8_t interface_index, | |||||
struct usart_status_t *status); | |||||
// USB_TO_SPI | |||||
RESULT usbtospi_init(uint8_t interface_index); | |||||
RESULT usbtospi_fini(uint8_t interface_index); | |||||
RESULT usbtospi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode); | |||||
RESULT usbtospi_io(uint8_t interface_index, uint8_t *out, uint8_t *in, | |||||
uint16_t bytelen); | |||||
// USB_TO_GPIO | |||||
RESULT usbtogpio_init(uint8_t interface_index); | |||||
RESULT usbtogpio_fini(uint8_t interface_index); | |||||
RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask, | |||||
uint32_t dir_mask, uint32_t pull_en_mask, | |||||
uint32_t input_pull_mask); | |||||
RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value); | |||||
RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value); | |||||
// USB_TO_ISSP | |||||
RESULT usbtoissp_init(uint8_t interface_index); | |||||
RESULT usbtoissp_fini(uint8_t interface_index); | |||||
RESULT usbtoissp_enter_program_mode(uint8_t interface_index, uint8_t mode); | |||||
RESULT usbtoissp_leave_program_mode(uint8_t interface_index, uint8_t mode); | |||||
RESULT usbtoissp_wait_and_poll(uint8_t interface_index); | |||||
RESULT usbtoissp_vector(uint8_t interface_index, uint8_t operate, uint8_t addr, | |||||
uint8_t data, uint8_t *buf); | |||||
// USB_TO_LPCICP | |||||
RESULT usbtolpcicp_init(uint8_t interface_index); | |||||
RESULT usbtolpcicp_fini(uint8_t interface_index); | |||||
RESULT usbtolpcicp_config(uint8_t interface_index); | |||||
RESULT usbtolpcicp_enter_program_mode(uint8_t interface_index); | |||||
RESULT usbtolpcicp_in(uint8_t interface_index, uint8_t *buff, uint16_t len); | |||||
RESULT usbtolpcicp_out(uint8_t interface_index, uint8_t *buff, uint16_t len); | |||||
RESULT usbtolpcicp_poll_ready(uint8_t interface_index, uint8_t data, | |||||
uint8_t *ret, uint8_t setmask, uint8_t clearmask, uint16_t pollcnt); | |||||
// USB_TO_JTAG_LL | |||||
RESULT usbtojtagll_init(uint8_t interface_index); | |||||
RESULT usbtojtagll_fini(uint8_t interface_index); | |||||
RESULT usbtojtagll_config(uint8_t interface_index, uint32_t kHz); | |||||
RESULT usbtojtagll_tms(uint8_t interface_index, uint8_t *tms, uint8_t bytelen); | |||||
RESULT usbtojtagll_tms_clocks(uint8_t interface_index, uint32_t bytelen, | |||||
uint8_t tms); | |||||
RESULT usbtojtagll_scan(uint8_t interface_index, uint8_t* data, | |||||
uint16_t bitlen, uint8_t tms_before_valid, | |||||
uint8_t tms_before, uint8_t tms_after0, | |||||
uint8_t tms_after1); | |||||
// USB_TO_JTAG_HL | |||||
RESULT usbtojtaghl_init(uint8_t interface_index); | |||||
RESULT usbtojtaghl_fini(uint8_t interface_index); | |||||
RESULT usbtojtaghl_config(uint8_t interface_index, uint32_t kHz, uint8_t ub, | |||||
uint8_t ua, uint16_t bb, uint16_t ba); | |||||
RESULT usbtojtaghl_ir(uint8_t interface_index, uint8_t *ir, uint16_t bitlen, | |||||
uint8_t idle, uint8_t want_ret); | |||||
RESULT usbtojtaghl_dr(uint8_t interface_index, uint8_t *dr, uint16_t bitlen, | |||||
uint8_t idle, uint8_t want_ret); | |||||
RESULT usbtojtaghl_tms(uint8_t interface_index, uint8_t *tms, uint16_t bitlen); | |||||
RESULT usbtojtaghl_runtest(uint8_t interface_index, uint32_t cycles); | |||||
RESULT usbtojtaghl_register_callback(uint8_t index, jtag_callback_t send_callback, | |||||
jtag_callback_t receive_callback); | |||||
// USB_TO_JTAG_RAW | |||||
RESULT usbtojtagraw_init(uint8_t interface_index); | |||||
RESULT usbtojtagraw_fini(uint8_t interface_index); | |||||
RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz); | |||||
RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi, | |||||
uint8_t *tms, uint8_t *tdo, uint32_t bitlen); | |||||
// USB_TO_C2 | |||||
RESULT usbtoc2_init(uint8_t interface_index); | |||||
RESULT usbtoc2_fini(uint8_t interface_index); | |||||
RESULT usbtoc2_writeaddr(uint8_t interface_index, uint8_t addr); | |||||
RESULT usbtoc2_readaddr(uint8_t interface_index, uint8_t *data); | |||||
RESULT usbtoc2_writedata(uint8_t interface_index, uint8_t *buf, uint8_t len); | |||||
RESULT usbtoc2_readdata(uint8_t interface_index, uint8_t *buf, uint8_t len); | |||||
// USB_TO_I2C | |||||
RESULT usbtoi2c_init(uint8_t interface_index); | |||||
RESULT usbtoi2c_fini(uint8_t interface_index); | |||||
RESULT usbtoi2c_config(uint8_t interface_index, uint16_t kHz, | |||||
uint16_t byte_interval, uint16_t max_dly); | |||||
RESULT usbtoi2c_read(uint8_t interface_index, uint16_t chip_addr, | |||||
uint8_t *data, uint16_t data_len, uint8_t stop, | |||||
bool nacklast); | |||||
RESULT usbtoi2c_write(uint8_t interface_index, uint16_t chip_addr, | |||||
uint8_t *data, uint16_t data_len, uint8_t stop); | |||||
// USB_TO_MSP430_JTAG | |||||
RESULT usbtomsp430jtag_init(uint8_t interface_index); | |||||
RESULT usbtomsp430jtag_fini(uint8_t interface_index); | |||||
RESULT usbtomsp430jtag_config(uint8_t interface_index, uint8_t has_test); | |||||
RESULT usbtomsp430jtag_ir(uint8_t interface_index, uint8_t *ir, | |||||
uint8_t want_ret); | |||||
RESULT usbtomsp430jtag_dr(uint8_t interface_index, uint32_t *dr, | |||||
uint8_t bitlen, uint8_t want_ret); | |||||
RESULT usbtomsp430jtag_tclk(uint8_t interface_index, uint8_t value); | |||||
RESULT usbtomsp430jtag_tclk_strobe(uint8_t interface_index, uint16_t cnt); | |||||
RESULT usbtomsp430jtag_reset(uint8_t interface_index); | |||||
RESULT usbtomsp430jtag_poll(uint8_t interface_index, uint32_t dr, | |||||
uint32_t mask, uint32_t value, uint8_t len, | |||||
uint16_t poll_cnt, uint8_t toggle_tclk); | |||||
// USB_TO_MSP430_SBW | |||||
RESULT usbtomsp430sbw_init(uint8_t interface_index); | |||||
RESULT usbtomsp430sbw_fini(uint8_t interface_index); | |||||
RESULT usbtomsp430sbw_config(uint8_t interface_index, uint8_t has_test); | |||||
RESULT usbtomsp430sbw_ir(uint8_t interface_index, uint8_t *ir, | |||||
uint8_t want_ret); | |||||
RESULT usbtomsp430sbw_dr(uint8_t interface_index, uint32_t *dr, | |||||
uint8_t bitlen, uint8_t want_ret); | |||||
RESULT usbtomsp430sbw_tclk(uint8_t interface_index, uint8_t value); | |||||
RESULT usbtomsp430sbw_tclk_strobe(uint8_t interface_index, uint16_t cnt); | |||||
RESULT usbtomsp430sbw_reset(uint8_t interface_index); | |||||
RESULT usbtomsp430sbw_poll(uint8_t interface_index, uint32_t dr, uint32_t mask, | |||||
uint32_t value, uint8_t len, uint16_t poll_cnt, | |||||
uint8_t toggle_tclk); | |||||
// USB_TO_POWER | |||||
RESULT usbtopwr_init(uint8_t interface_index); | |||||
RESULT usbtopwr_fini(uint8_t interface_index); | |||||
RESULT usbtopwr_config(uint8_t interface_index); | |||||
RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV); | |||||
// USB_TO_POLL | |||||
RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us); | |||||
RESULT usbtopoll_end(void); | |||||
RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size, | |||||
uint32_t mask, uint32_t value); | |||||
RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size, | |||||
uint32_t mask, uint32_t value); | |||||
RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff); | |||||
// USB_TO_SWD | |||||
RESULT usbtoswd_init(uint8_t interface_index); | |||||
RESULT usbtoswd_fini(uint8_t interface_index); | |||||
RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry, | |||||
uint16_t dly); | |||||
RESULT usbtoswd_seqout(uint8_t interface_index, uint8_t *data, uint16_t bitlen); | |||||
RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen); | |||||
RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request, | |||||
uint32_t *data, uint8_t *ack); | |||||
// USB_TO_SWIM | |||||
RESULT usbtoswim_init(uint8_t interface_index); | |||||
RESULT usbtoswim_fini(uint8_t interface_index); | |||||
RESULT usbtoswim_config(uint8_t interface_index, uint8_t mHz, uint8_t cnt0, | |||||
uint8_t cnt1); | |||||
RESULT usbtoswim_srst(uint8_t interface_index); | |||||
RESULT usbtoswim_wotf(uint8_t interface_index, uint8_t *data, | |||||
uint16_t bytelen, uint32_t addr); | |||||
RESULT usbtoswim_rotf(uint8_t interface_index, uint8_t *data, | |||||
uint16_t bytelen, uint32_t addr); | |||||
RESULT usbtoswim_sync(uint8_t interface_index, uint8_t mHz); | |||||
RESULT usbtoswim_enable(uint8_t interface_index); | |||||
// USB_TO_BDM | |||||
RESULT usbtobdm_init(uint8_t interface_index); | |||||
RESULT usbtobdm_fini(uint8_t interface_index); | |||||
RESULT usbtobdm_sync(uint8_t interface_index, uint16_t *khz); | |||||
RESULT usbtobdm_transact(uint8_t interface_index, uint8_t *out, | |||||
uint8_t outlen, uint8_t *in, uint8_t inlen, uint8_t delay, uint8_t ack); | |||||
// USB_TO_DUSI | |||||
RESULT usbtodusi_init(uint8_t interface_index); | |||||
RESULT usbtodusi_fini(uint8_t interface_index); | |||||
RESULT usbtodusi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode); | |||||
RESULT usbtodusi_io(uint8_t interface_index, uint8_t *mo, uint8_t *mi, | |||||
uint8_t *so, uint8_t *si, uint32_t bitlen); | |||||
// USB_TO_MICROWIRE | |||||
RESULT usbtomicrowire_init(uint8_t interface_index); | |||||
RESULT usbtomicrowire_fini(uint8_t interface_index); | |||||
RESULT usbtomicrowire_config(uint8_t interface_index, uint16_t kHz, | |||||
uint8_t sel_polarity); | |||||
RESULT usbtomicrowire_transport(uint8_t interface_index, | |||||
uint32_t opcode, uint8_t opcode_bitlen, | |||||
uint32_t addr, uint8_t addr_bitlen, | |||||
uint32_t data, uint8_t data_bitlen, | |||||
uint8_t *reply, uint8_t reply_bitlen); | |||||
RESULT usbtomicrowire_poll(uint8_t interface_index, uint16_t interval_us, | |||||
uint16_t retry_cnt); | |||||
// USB_TO_PWM | |||||
RESULT usbtopwm_init(uint8_t interface_index); | |||||
RESULT usbtopwm_fini(uint8_t interface_index); | |||||
RESULT usbtopwm_config(uint8_t interface_index, uint16_t kHz, uint8_t mode); | |||||
RESULT usbtopwm_out(uint8_t interface_index, uint16_t count, uint16_t *rate); | |||||
RESULT usbtopwm_in(uint8_t interface_index, uint16_t count, uint16_t *rate); | |||||
#endif /* __USBTOXXX_H_INCLUDED__ */ | |||||
@@ -0,0 +1,169 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifndef __USBTOXXX_INTERNAL_H_INCLUDED__ | |||||
#define __USBTOXXX_INTERNAL_H_INCLUDED__ | |||||
// USB_TO_XXX USB Commands | |||||
// Page0 | |||||
#define USB_TO_USART (VERSALOON_USB_TO_XXX_CMD_START + 0x00) | |||||
#define USB_TO_SPI (VERSALOON_USB_TO_XXX_CMD_START + 0x01) | |||||
#define USB_TO_I2C (VERSALOON_USB_TO_XXX_CMD_START + 0x02) | |||||
#define USB_TO_GPIO (VERSALOON_USB_TO_XXX_CMD_START + 0x03) | |||||
#define USB_TO_CAN (VERSALOON_USB_TO_XXX_CMD_START + 0x04) | |||||
#define USB_TO_PWM (VERSALOON_USB_TO_XXX_CMD_START + 0x05) | |||||
#define USB_TO_ADC (VERSALOON_USB_TO_XXX_CMD_START + 0x06) | |||||
#define USB_TO_DAC (VERSALOON_USB_TO_XXX_CMD_START + 0x07) | |||||
#define USB_TO_MICROWIRE (VERSALOON_USB_TO_XXX_CMD_START + 0x08) | |||||
#define USB_TO_SWIM (VERSALOON_USB_TO_XXX_CMD_START + 0x09) | |||||
#define USB_TO_DUSI (VERSALOON_USB_TO_XXX_CMD_START + 0x0A) | |||||
// Page1 | |||||
#define USB_TO_JTAG_LL (VERSALOON_USB_TO_XXX_CMD_START + 0x20) | |||||
#define USB_TO_JTAG_HL (VERSALOON_USB_TO_XXX_CMD_START + 0x21) | |||||
#define USB_TO_ISSP (VERSALOON_USB_TO_XXX_CMD_START + 0x22) | |||||
#define USB_TO_C2 (VERSALOON_USB_TO_XXX_CMD_START + 0x23) | |||||
#define USB_TO_SBW (VERSALOON_USB_TO_XXX_CMD_START + 0x24) | |||||
#define USB_TO_LPCICP (VERSALOON_USB_TO_XXX_CMD_START + 0x25) | |||||
#define USB_TO_SWD (VERSALOON_USB_TO_XXX_CMD_START + 0x26) | |||||
#define USB_TO_JTAG_RAW (VERSALOON_USB_TO_XXX_CMD_START + 0x27) | |||||
#define USB_TO_BDM (VERSALOON_USB_TO_XXX_CMD_START + 0x28) | |||||
#define USB_TO_MSP430_JTAG (VERSALOON_USB_TO_XXX_CMD_START + 0x38) | |||||
// Page2 | |||||
#define USB_TO_POWER (VERSALOON_USB_TO_XXX_CMD_START + 0x40) | |||||
#define USB_TO_DELAY (VERSALOON_USB_TO_XXX_CMD_START + 0x41) | |||||
#define USB_TO_POLL (VERSALOON_USB_TO_XXX_CMD_START + 0x42) | |||||
#define USB_TO_INFO (VERSALOON_USB_TO_XXX_CMD_START + 0x5E) | |||||
#define USB_TO_ALL (VERSALOON_USB_TO_XXX_CMD_START + 0x5F) | |||||
// USB_TO_XXX Masks | |||||
#define USB_TO_XXX_CMDMASK 0xF8 | |||||
#define USB_TO_XXX_CMDSHIFT 3 | |||||
#define USB_TO_XXX_IDXMASK 0x07 | |||||
// USB_TO_XXX Sub Commands | |||||
// Common Sub Commands | |||||
#define USB_TO_XXX_INIT (0x00 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_FINI (0x01 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_CONFIG (0x02 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_GETHWINFO (0x03 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_STATUS (0X04 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_IN_OUT (0x05 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_IN (0x06 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_OUT (0x07 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_POLL (0x08 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_SPECIAL (0x09 << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_RESET (0x0A << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_SYNC (0x0B << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_ENABLE (0x0C << USB_TO_XXX_CMDSHIFT) | |||||
#define USB_TO_XXX_DISABLE (0x0D << USB_TO_XXX_CMDSHIFT) | |||||
// USB_TO_POLL | |||||
#define USB_TO_POLL_START 0x00 | |||||
#define USB_TO_POLL_END 0x01 | |||||
#define USB_TO_POLL_CHECKOK 0x02 | |||||
#define USB_TO_POLL_CHECKFAIL 0x03 | |||||
#define USB_TO_POLL_VERIFYBUFF 0x04 | |||||
// USB_TO_XXX Replys | |||||
#define USB_TO_XXX_OK 0x00 | |||||
#define USB_TO_XXX_FAILED 0x01 | |||||
#define USB_TO_XXX_TIME_OUT 0x02 | |||||
#define USB_TO_XXX_INVALID_INDEX 0x03 | |||||
#define USB_TO_XXX_INVALID_PARA 0x04 | |||||
#define USB_TO_XXX_INVALID_CMD 0x05 | |||||
#define USB_TO_XXX_CMD_NOT_SUPPORT 0x06 | |||||
// USB_TO_XXX | |||||
RESULT usbtoxxx_add_pending(uint8_t type, uint8_t cmd, uint16_t | |||||
actual_szie, uint16_t want_pos, | |||||
uint16_t want_size, uint8_t *buffer); | |||||
RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf, | |||||
uint16_t cmdlen, uint16_t retlen, | |||||
uint8_t *wantbuf, uint16_t wantpos, | |||||
uint16_t wantlen, uint8_t collect); | |||||
#define usbtoxxx_init_command(type, port) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_INIT | (port)), \ | |||||
NULL, 0, 0, NULL, 0, 0, 0) | |||||
#define usbtoxxx_fini_command(type, port) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_FINI | (port)), \ | |||||
NULL, 0, 0, NULL, 0, 0, 0) | |||||
#define usbtoxxx_conf_command(type, port, cmdbuf, cmdlen) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_CONFIG | (port)), \ | |||||
(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) | |||||
#define usbtoxxx_inout_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ | |||||
wantpos, wantlen, c) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_IN_OUT | (port)), \ | |||||
(cmdbuf), (cmdlen), (retlen), (wantbuf), \ | |||||
(wantpos), (wantlen), (c)) | |||||
#define usbtoxxx_in_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ | |||||
wantpos, wantlen, c) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_IN | (port)), (cmdbuf), \ | |||||
(cmdlen), (retlen), (wantbuf), (wantpos), \ | |||||
(wantlen), (c)) | |||||
#define usbtoxxx_out_command(type, port, cmdbuf, cmdlen, c) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_OUT | (port)), (cmdbuf), \ | |||||
(cmdlen), 0, NULL, 0, 0, (c)) | |||||
#define usbtoxxx_poll_command(type, port, cmdbuf, cmdlen, retbuf, retlen) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_POLL | (port)), (cmdbuf),\ | |||||
(cmdlen), (retlen), (retbuf), 0, (retlen), 0) | |||||
#define usbtoxxx_status_command(type, port, retlen, wantbuf, wantpos, wantlen, c)\ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_STATUS | (port)), \ | |||||
NULL, 0, (retlen), (wantbuf), (wantpos), \ | |||||
(wantlen), (c)) | |||||
#define usbtoxxx_special_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ | |||||
wantpos, wantlen, c) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_SPECIAL | (port)), \ | |||||
(cmdbuf), (cmdlen), retlen, wantbuf, \ | |||||
wantpos, wantlen, (c)) | |||||
#define usbtoxxx_reset_command(type, port, cmdbuf, cmdlen) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_RESET | (port)), \ | |||||
(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) | |||||
#define usbtoxxx_sync_command(type, port, cmdbuf, cmdlen, retlen, wantbuf) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_SYNC | (port)), \ | |||||
(cmdbuf), (cmdlen), (retlen), (wantbuf), 0, \ | |||||
(retlen), 0) | |||||
#define usbtoxxx_enable_command(type, port, cmdbuf, cmdlen) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_ENABLE | (port)), \ | |||||
(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) | |||||
#define usbtoxxx_disable_command(type, port, cmdbuf, cmdlen) \ | |||||
usbtoxxx_add_command((type), (USB_TO_XXX_DISABLE | (port)), \ | |||||
(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) | |||||
// USB_TO_SPI | |||||
#define USB_TO_SPI_BAUDRATE_MSK 0x1F | |||||
#define USB_TO_SPI_CPOL_MSK 0x20 | |||||
#define USB_TO_SPI_CPHA_MSK 0x40 | |||||
#define USB_TO_SPI_MSB_FIRST 0x80 | |||||
// USB_TO_DUSI | |||||
#define USB_TO_DUSI_BAUDRATE_MSK 0x1F | |||||
#define USB_TO_DUSI_CPOL_MSK 0x20 | |||||
#define USB_TO_DUSI_CPHA_MSK 0x40 | |||||
#define USB_TO_DUSI_MSB_FIRST 0x80 | |||||
// USB_TO_GPIO | |||||
#define USB_TO_GPIO_DIR_MSK 0x01 | |||||
#endif /* __USBTOXXX_INTERNAL_H_INCLUDED__ */ | |||||
@@ -0,0 +1,398 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include "versaloon_include.h" | |||||
#include "versaloon.h" | |||||
#include "versaloon_internal.h" | |||||
#include "usbtoxxx/usbtoxxx.h" | |||||
uint8_t *versaloon_buf = NULL; | |||||
uint8_t *versaloon_cmd_buf = NULL; | |||||
uint16_t versaloon_buf_size; | |||||
struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; | |||||
uint16_t versaloon_pending_idx = 0; | |||||
usb_dev_handle *versaloon_usb_device_handle = NULL; | |||||
static uint32_t versaloon_usb_to = VERSALOON_TIMEOUT; | |||||
RESULT versaloon_init(void); | |||||
RESULT versaloon_fini(void); | |||||
RESULT versaloon_get_target_voltage(uint16_t *voltage); | |||||
RESULT versaloon_set_target_voltage(uint16_t voltage); | |||||
RESULT versaloon_delay_ms(uint16_t ms); | |||||
RESULT versaloon_delay_us(uint16_t us); | |||||
struct versaloon_interface_t versaloon_interface = | |||||
{ | |||||
.init = versaloon_init, | |||||
.fini = versaloon_fini, | |||||
{// adaptors | |||||
{// target_voltage | |||||
.get = versaloon_get_target_voltage, | |||||
.set = versaloon_set_target_voltage, | |||||
}, | |||||
{// gpio | |||||
.init = usbtogpio_init, | |||||
.fini = usbtogpio_fini, | |||||
.config = usbtogpio_config, | |||||
.out = usbtogpio_out, | |||||
.in = usbtogpio_in, | |||||
}, | |||||
{// delay | |||||
.delayms = versaloon_delay_ms, | |||||
.delayus = versaloon_delay_us, | |||||
}, | |||||
{// swd | |||||
.init = usbtoswd_init, | |||||
.fini = usbtoswd_fini, | |||||
.config = usbtoswd_config, | |||||
.seqout = usbtoswd_seqout, | |||||
.seqin = usbtoswd_seqin, | |||||
.transact = usbtoswd_transact, | |||||
}, | |||||
{// jtag_raw | |||||
.init = usbtojtagraw_init, | |||||
.fini = usbtojtagraw_fini, | |||||
.config = usbtojtagraw_config, | |||||
.execute = usbtojtagraw_execute, | |||||
}, | |||||
.peripheral_commit = usbtoxxx_execute_command, | |||||
}, | |||||
{// usb_setting | |||||
.vid = VERSALOON_VID, | |||||
.pid = VERSALOON_PID, | |||||
.ep_out = VERSALOON_OUTP, | |||||
.ep_in = VERSALOON_INP, | |||||
.interface = VERSALOON_IFACE, | |||||
.serialstring = NULL, | |||||
.buf_size = 256, | |||||
} | |||||
}; | |||||
// programmer_cmd | |||||
static uint32_t versaloon_pending_id = 0; | |||||
static versaloon_callback_t versaloon_callback = NULL; | |||||
static void *versaloon_extra_data = NULL; | |||||
static struct versaloon_want_pos_t *versaloon_want_pos = NULL; | |||||
void versaloon_set_pending_id(uint32_t id) | |||||
{ | |||||
versaloon_pending_id = id; | |||||
} | |||||
void versaloon_set_callback(versaloon_callback_t callback) | |||||
{ | |||||
versaloon_callback = callback; | |||||
} | |||||
void versaloon_set_extra_data(void * p) | |||||
{ | |||||
versaloon_extra_data = p; | |||||
} | |||||
void versaloon_free_want_pos(void) | |||||
{ | |||||
uint16_t i; | |||||
struct versaloon_want_pos_t *tmp, *free_tmp; | |||||
tmp = versaloon_want_pos; | |||||
while (tmp != NULL) | |||||
{ | |||||
free_tmp = tmp; | |||||
tmp = tmp->next; | |||||
free(free_tmp); | |||||
} | |||||
versaloon_want_pos = NULL; | |||||
for (i = 0; i < dimof(versaloon_pending); i++) | |||||
{ | |||||
tmp = versaloon_pending[i].pos; | |||||
while (tmp != NULL) | |||||
{ | |||||
free_tmp = tmp; | |||||
tmp = tmp->next; | |||||
free(free_tmp); | |||||
} | |||||
versaloon_pending[i].pos = NULL; | |||||
} | |||||
} | |||||
RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff) | |||||
{ | |||||
struct versaloon_want_pos_t *new_pos = NULL; | |||||
new_pos = (struct versaloon_want_pos_t *)malloc(sizeof(*new_pos)); | |||||
if (NULL == new_pos) | |||||
{ | |||||
LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); | |||||
return ERRCODE_NOT_ENOUGH_MEMORY; | |||||
} | |||||
new_pos->offset = offset; | |||||
new_pos->size = size; | |||||
new_pos->buff = buff; | |||||
new_pos->next = NULL; | |||||
if (NULL == versaloon_want_pos) | |||||
{ | |||||
versaloon_want_pos = new_pos; | |||||
} | |||||
else | |||||
{ | |||||
struct versaloon_want_pos_t *tmp = versaloon_want_pos; | |||||
while (tmp->next != NULL) | |||||
{ | |||||
tmp = tmp->next; | |||||
} | |||||
tmp->next = new_pos; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
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) | |||||
{ | |||||
#if PARAM_CHECK | |||||
if (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_INDEX, versaloon_pending_idx, | |||||
"versaloon pending data"); | |||||
return ERROR_FAIL; | |||||
} | |||||
#endif | |||||
versaloon_pending[versaloon_pending_idx].type = type; | |||||
versaloon_pending[versaloon_pending_idx].cmd = cmd; | |||||
versaloon_pending[versaloon_pending_idx].actual_data_size = actual_szie; | |||||
versaloon_pending[versaloon_pending_idx].want_data_pos = want_pos; | |||||
versaloon_pending[versaloon_pending_idx].want_data_size = want_size; | |||||
versaloon_pending[versaloon_pending_idx].data_buffer = buffer; | |||||
versaloon_pending[versaloon_pending_idx].collect = collect; | |||||
versaloon_pending[versaloon_pending_idx].id = versaloon_pending_id; | |||||
versaloon_pending_id = 0; | |||||
versaloon_pending[versaloon_pending_idx].extra_data = versaloon_extra_data; | |||||
versaloon_extra_data = NULL; | |||||
versaloon_pending[versaloon_pending_idx].callback = versaloon_callback; | |||||
versaloon_callback = NULL; | |||||
versaloon_pending[versaloon_pending_idx].pos = versaloon_want_pos; | |||||
versaloon_want_pos = NULL; | |||||
versaloon_pending_idx++; | |||||
return ERROR_OK; | |||||
} | |||||
RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen) | |||||
{ | |||||
int ret; | |||||
#if PARAM_CHECK | |||||
if (NULL == versaloon_buf) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); | |||||
return ERRCODE_INVALID_BUFFER; | |||||
} | |||||
if ((0 == out_len) || (out_len > versaloon_interface.usb_setting.buf_size)) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__); | |||||
return ERRCODE_INVALID_PARAMETER; | |||||
} | |||||
#endif | |||||
ret = usb_bulk_write(versaloon_usb_device_handle, | |||||
versaloon_interface.usb_setting.ep_out, (char *)versaloon_buf, | |||||
out_len, versaloon_usb_to); | |||||
if (ret != out_len) | |||||
{ | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "send usb data", | |||||
usb_strerror()); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
if (inlen != NULL) | |||||
{ | |||||
ret = usb_bulk_read(versaloon_usb_device_handle, | |||||
versaloon_interface.usb_setting.ep_in, (char *)versaloon_buf, | |||||
versaloon_interface.usb_setting.buf_size, versaloon_usb_to); | |||||
if (ret > 0) | |||||
{ | |||||
*inlen = (uint16_t)ret; | |||||
return ERROR_OK; | |||||
} | |||||
else | |||||
{ | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "receive usb data", | |||||
usb_strerror()); | |||||
return ERROR_FAIL; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
return ERROR_OK; | |||||
} | |||||
} | |||||
#define VERSALOON_RETRY_CNT 10 | |||||
RESULT versaloon_init(void) | |||||
{ | |||||
uint16_t ret = 0; | |||||
uint8_t retry; | |||||
uint32_t timeout_tmp; | |||||
// malloc temporary buffer | |||||
versaloon_buf = | |||||
(uint8_t *)malloc(versaloon_interface.usb_setting.buf_size); | |||||
if (NULL == versaloon_buf) | |||||
{ | |||||
LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); | |||||
return ERRCODE_NOT_ENOUGH_MEMORY; | |||||
} | |||||
// connect to versaloon | |||||
timeout_tmp = versaloon_usb_to; | |||||
// not output error message when connectting | |||||
// 100ms delay when connect | |||||
versaloon_usb_to = 100; | |||||
for (retry = 0; retry < VERSALOON_RETRY_CNT; retry++) | |||||
{ | |||||
versaloon_buf[0] = VERSALOON_GET_INFO; | |||||
if ((ERROR_OK == versaloon_send_command(1, &ret)) && (ret >= 3)) | |||||
{ | |||||
break; | |||||
} | |||||
} | |||||
versaloon_usb_to = timeout_tmp; | |||||
if (VERSALOON_RETRY_CNT == retry) | |||||
{ | |||||
versaloon_fini(); | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
versaloon_buf[ret] = 0; | |||||
versaloon_buf_size = versaloon_buf[0] + (versaloon_buf[1] << 8); | |||||
versaloon_interface.usb_setting.buf_size = versaloon_buf_size; | |||||
LOG_INFO("%s", versaloon_buf + 2); | |||||
// free temporary buffer | |||||
free(versaloon_buf); | |||||
versaloon_buf = NULL; | |||||
versaloon_buf = | |||||
(uint8_t *)malloc(versaloon_interface.usb_setting.buf_size); | |||||
if (NULL == versaloon_buf) | |||||
{ | |||||
versaloon_fini(); | |||||
LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); | |||||
return ERRCODE_NOT_ENOUGH_MEMORY; | |||||
} | |||||
versaloon_cmd_buf = | |||||
(uint8_t *)malloc(versaloon_interface.usb_setting.buf_size - 3); | |||||
if (NULL == versaloon_cmd_buf) | |||||
{ | |||||
versaloon_fini(); | |||||
LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); | |||||
return ERRCODE_NOT_ENOUGH_MEMORY; | |||||
} | |||||
if (ERROR_OK != usbtoxxx_init()) | |||||
{ | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION, "initialize usbtoxxx"); | |||||
return ERROR_FAIL; | |||||
} | |||||
return versaloon_get_target_voltage(&ret); | |||||
} | |||||
RESULT versaloon_fini(void) | |||||
{ | |||||
if (versaloon_usb_device_handle != NULL) | |||||
{ | |||||
usbtoxxx_fini(); | |||||
versaloon_free_want_pos(); | |||||
versaloon_usb_device_handle = NULL; | |||||
if (versaloon_buf != NULL) | |||||
{ | |||||
free(versaloon_buf); | |||||
versaloon_buf = NULL; | |||||
} | |||||
if (versaloon_cmd_buf != NULL) | |||||
{ | |||||
free(versaloon_cmd_buf); | |||||
versaloon_cmd_buf = NULL; | |||||
} | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
RESULT versaloon_set_target_voltage(uint16_t voltage) | |||||
{ | |||||
usbtopwr_init(0); | |||||
usbtopwr_config(0); | |||||
usbtopwr_output(0, voltage); | |||||
usbtopwr_fini(0); | |||||
return usbtoxxx_execute_command(); | |||||
} | |||||
RESULT versaloon_get_target_voltage(uint16_t *voltage) | |||||
{ | |||||
uint16_t inlen; | |||||
#if PARAM_CHECK | |||||
if (NULL == versaloon_buf) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); | |||||
return ERRCODE_INVALID_BUFFER; | |||||
} | |||||
if (NULL == voltage) | |||||
{ | |||||
LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__); | |||||
return ERRCODE_INVALID_PARAMETER; | |||||
} | |||||
#endif | |||||
versaloon_buf[0] = VERSALOON_GET_TVCC; | |||||
if ((ERROR_OK != versaloon_send_command(1, &inlen)) || (inlen != 2)) | |||||
{ | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon"); | |||||
return ERRCODE_FAILURE_OPERATION; | |||||
} | |||||
else | |||||
{ | |||||
*voltage = versaloon_buf[0] + (versaloon_buf[1] << 8); | |||||
return ERROR_OK; | |||||
} | |||||
} | |||||
RESULT versaloon_delay_ms(uint16_t ms) | |||||
{ | |||||
return usbtodelay_delay(ms | 0x8000); | |||||
} | |||||
RESULT versaloon_delay_us(uint16_t us) | |||||
{ | |||||
return usbtodelay_delay(us & 0x7FFF); | |||||
} | |||||
@@ -0,0 +1,119 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifndef __VERSALOON_H_INCLUDED__ | |||||
#define __VERSALOON_H_INCLUDED__ | |||||
struct usart_status_t | |||||
{ | |||||
uint32_t tx_buff_avail; | |||||
uint32_t tx_buff_size; | |||||
uint32_t rx_buff_avail; | |||||
uint32_t rx_buff_size; | |||||
}; | |||||
#include "usbtoxxx/usbtoxxx.h" | |||||
// GPIO pins | |||||
#define GPIO_SRST (1 << 0) | |||||
#define GPIO_TRST (1 << 1) | |||||
#define GPIO_USR1 (1 << 2) | |||||
#define GPIO_USR2 (1 << 3) | |||||
#define GPIO_TCK (1 << 4) | |||||
#define GPIO_TDO (1 << 5) | |||||
#define GPIO_TDI (1 << 6) | |||||
#define GPIO_RTCK (1 << 7) | |||||
#define GPIO_TMS (1 << 8) | |||||
struct interface_gpio_t | |||||
{ | |||||
RESULT (*init)(uint8_t interface_index); | |||||
RESULT (*fini)(uint8_t interface_index); | |||||
RESULT (*config)(uint8_t interface_index, uint32_t pin_mask, uint32_t io, | |||||
uint32_t pull_en_mask, uint32_t input_pull_mask); | |||||
RESULT (*out)(uint8_t interface_index, uint32_t pin_mask, uint32_t value); | |||||
RESULT (*in)(uint8_t interface_index, uint32_t pin_mask, uint32_t *value); | |||||
}; | |||||
struct interface_delay_t | |||||
{ | |||||
RESULT (*delayms)(uint16_t ms); | |||||
RESULT (*delayus)(uint16_t us); | |||||
}; | |||||
struct interface_swd_t | |||||
{ | |||||
RESULT (*init)(uint8_t interface_index); | |||||
RESULT (*fini)(uint8_t interface_index); | |||||
RESULT (*config)(uint8_t interface_index, uint8_t trn, uint16_t retry, | |||||
uint16_t dly); | |||||
RESULT (*seqout)(uint8_t interface_index, uint8_t *data, uint16_t bitlen); | |||||
RESULT (*seqin)(uint8_t interface_index, uint8_t *data, uint16_t bitlen); | |||||
RESULT (*transact)(uint8_t interface_index, uint8_t request, | |||||
uint32_t *data, uint8_t *ack); | |||||
}; | |||||
struct interface_jtag_raw_t | |||||
{ | |||||
RESULT (*init)(uint8_t interface_index); | |||||
RESULT (*fini)(uint8_t interface_index); | |||||
RESULT (*config)(uint8_t interface_index, uint32_t kHz); | |||||
RESULT (*execute)(uint8_t interface_index, uint8_t* tdi, uint8_t* tms, | |||||
uint8_t *tdo, uint32_t bitlen); | |||||
}; | |||||
struct interface_target_voltage_t | |||||
{ | |||||
RESULT (*get)(uint16_t *voltage); | |||||
RESULT (*set)(uint16_t voltage); | |||||
}; | |||||
struct versaloon_adaptors_t | |||||
{ | |||||
struct interface_target_voltage_t target_voltage; | |||||
struct interface_gpio_t gpio; | |||||
struct interface_delay_t delay; | |||||
struct interface_swd_t swd; | |||||
struct interface_jtag_raw_t jtag_raw; | |||||
RESULT (*peripheral_commit)(void); | |||||
}; | |||||
struct versaloon_usb_setting_t | |||||
{ | |||||
uint16_t vid; | |||||
uint16_t pid; | |||||
uint8_t ep_out; | |||||
uint8_t ep_in; | |||||
uint8_t interface; | |||||
char *serialstring; | |||||
uint16_t buf_size; | |||||
}; | |||||
struct versaloon_interface_t | |||||
{ | |||||
RESULT (*init)(void); | |||||
RESULT (*fini)(void); | |||||
struct versaloon_adaptors_t adaptors; | |||||
struct versaloon_usb_setting_t usb_setting; | |||||
}; | |||||
extern struct versaloon_interface_t versaloon_interface; | |||||
extern usb_dev_handle *versaloon_usb_device_handle; | |||||
#endif /* __VERSALOON_H_INCLUDED__ */ | |||||
@@ -0,0 +1,100 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
// This file is used to include different header and macros | |||||
// according to different platform | |||||
#include <jtag/interface.h> | |||||
#include <jtag/commands.h> | |||||
#include "usb_common.h" | |||||
#define PARAM_CHECK 1 | |||||
#define sleep_ms(ms) jtag_sleep((ms) * 1000) | |||||
#define dimof(arr) (sizeof(arr) / sizeof((arr)[0])) | |||||
#define TO_STR(name) #name | |||||
#define RESULT int | |||||
#define LOG_BUG LOG_ERROR | |||||
// Common error messages | |||||
#define ERRMSG_NOT_ENOUGH_MEMORY "Lack of memory." | |||||
#define ERRCODE_NOT_ENOUGH_MEMORY ERROR_FAIL | |||||
#define ERRMSG_INVALID_VALUE "%d is invalid for %s." | |||||
#define ERRMSG_INVALID_INDEX "Index %d is invalid for %s." | |||||
#define ERRMSG_INVALID_USAGE "Invalid usage of %s" | |||||
#define ERRMSG_INVALID_TARGET "Invalid %s" | |||||
#define ERRMSG_INVALID_PARAMETER "Invalid parameter of %s." | |||||
#define ERRMSG_INVALID_INTERFACE_NUM "invalid inteface %d" | |||||
#define ERRMSG_INVALID_BUFFER "Buffer %s is not valid." | |||||
#define ERRCODE_INVALID_BUFFER ERROR_FAIL | |||||
#define ERRCODE_INVALID_PARAMETER ERROR_FAIL | |||||
#define ERRMSG_NOT_SUPPORT_BY "%s is not supported by %s." | |||||
#define ERRMSG_FAILURE_OPERATION "Fail to %s." | |||||
#define ERRMSG_FAILURE_OPERATION_ERRSTRING "Fail to %s, error string is %s." | |||||
#define ERRMSG_FAILURE_OPERATION_MESSAGE "Fail to %s, %s" | |||||
#define ERRCODE_FAILURE_OPERATION ERROR_FAIL | |||||
#define GET_U16_MSBFIRST(p) ( ((*((uint8_t *)(p) + 0)) << 8) | \ | |||||
((*((uint8_t *)(p) + 1)) << 0)) | |||||
#define GET_U32_MSBFIRST(p) ( ((*((uint8_t *)(p) + 0)) << 24) | \ | |||||
((*((uint8_t *)(p) + 1)) << 16) | \ | |||||
((*((uint8_t *)(p) + 2)) << 8) | \ | |||||
((*((uint8_t *)(p) + 3)) << 0)) | |||||
#define GET_U16_LSBFIRST(p) ( ((*((uint8_t *)(p) + 0)) << 0) | \ | |||||
((*((uint8_t *)(p) + 1)) << 8)) | |||||
#define GET_U32_LSBFIRST(p) ( ((*((uint8_t *)(p) + 0)) << 0) | \ | |||||
((*((uint8_t *)(p) + 1)) << 8) | \ | |||||
((*((uint8_t *)(p) + 2)) << 16) | \ | |||||
((*((uint8_t *)(p) + 3)) << 24)) | |||||
#define SET_U16_MSBFIRST(p, v) \ | |||||
do{\ | |||||
*((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 8) & 0xFF;\ | |||||
*((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 0) & 0xFF;\ | |||||
} while (0) | |||||
#define SET_U32_MSBFIRST(p, v) \ | |||||
do{\ | |||||
*((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 24) & 0xFF;\ | |||||
*((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 16) & 0xFF;\ | |||||
*((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 8) & 0xFF;\ | |||||
*((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 0) & 0xFF;\ | |||||
} while (0) | |||||
#define SET_U16_LSBFIRST(p, v) \ | |||||
do{\ | |||||
*((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 0) & 0xFF;\ | |||||
*((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 8) & 0xFF;\ | |||||
} while (0) | |||||
#define SET_U32_LSBFIRST(p, v) \ | |||||
do{\ | |||||
*((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 0) & 0xFF;\ | |||||
*((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 8) & 0xFF;\ | |||||
*((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 16) & 0xFF;\ | |||||
*((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 24) & 0xFF;\ | |||||
} while (0) | |||||
#define GET_LE_U16(p) GET_U16_LSBFIRST(p) | |||||
#define GET_LE_U32(p) GET_U32_LSBFIRST(p) | |||||
#define GET_BE_U16(p) GET_U16_MSBFIRST(p) | |||||
#define GET_BE_U32(p) GET_U32_MSBFIRST(p) | |||||
#define SET_LE_U16(p, v) SET_U16_LSBFIRST(p, v) | |||||
#define SET_LE_U32(p, v) SET_U32_LSBFIRST(p, v) | |||||
#define SET_BE_U16(p, v) SET_U16_MSBFIRST(p, v) | |||||
#define SET_BE_U32(p, v) SET_U32_MSBFIRST(p, v) |
@@ -0,0 +1,118 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||||
***************************************************************************/ | |||||
#ifndef __VERSALOON_INTERNAL_H_INCLUDED__ | |||||
#define __VERSALOON_INTERNAL_H_INCLUDED__ | |||||
#define VERSALOON_PRODUCTSTRING_INDEX 2 | |||||
#define VERSALOON_SERIALSTRING_INDEX 3 | |||||
#define VERSALOON_PRODUCTSTRING "Versaloon" | |||||
#define VERSALOON_VID 0x0483 | |||||
#define VERSALOON_PID 0xA038 | |||||
#define VERSALOON_INP 0x82 | |||||
#define VERSALOON_OUTP 0x03 | |||||
#define VERSALOON_IFACE 0x00 | |||||
#define VERSALOON_FULL 1 | |||||
#define VERSALOON_MINI 2 | |||||
#define VERSALOON_NANO 3 | |||||
#define VERSALOON_TIMEOUT 5000 | |||||
#define VERSALOON_TIMEOUT_LONG 60000 | |||||
// USB Commands | |||||
// Common Commands | |||||
#define VERSALOON_COMMON_CMD_START 0x00 | |||||
#define VERSALOON_COMMON_CMD_END 0x0F | |||||
#define VERSALOON_GET_INFO 0x00 | |||||
#define VERSALOON_GET_TVCC 0x01 | |||||
#define VERSALOON_GET_HARDWARE 0x02 | |||||
#define VERSALOON_GET_OFFLINE_SIZE 0x08 | |||||
#define VERSALOON_ERASE_OFFLINE_DATA 0x09 | |||||
#define VERSALOON_WRITE_OFFLINE_DATA 0x0A | |||||
#define VERSALOON_GET_OFFLINE_CHECKSUM 0x0B | |||||
#define VERSALOON_FW_UPDATE 0x0F | |||||
#define VERSALOON_FW_UPDATE_KEY 0xAA | |||||
// MCU Command | |||||
#define VERSALOON_MCU_CMD_START 0x10 | |||||
#define VERSALOON_MCU_CMD_END 0x1F | |||||
// USB_TO_XXX Command | |||||
#define VERSALOON_USB_TO_XXX_CMD_START 0x20 | |||||
#define VERSALOON_USB_TO_XXX_CMD_END 0x7F | |||||
// VSLLink Command | |||||
#define VERSALOON_VSLLINK_CMD_START 0x80 | |||||
#define VERSALOON_VSLLINK_CMD_END 0xFF | |||||
// Mass-product | |||||
#define MP_OK 0x00 | |||||
#define MP_FAIL 0x01 | |||||
#define MP_ISSP 0x11 | |||||
// pending struct | |||||
#define VERSALOON_MAX_PENDING_NUMBER 4096 | |||||
typedef RESULT (*versaloon_callback_t)(void *, uint8_t *, uint8_t *); | |||||
struct versaloon_want_pos_t | |||||
{ | |||||
uint16_t offset; | |||||
uint16_t size; | |||||
uint8_t *buff; | |||||
struct versaloon_want_pos_t *next; | |||||
}; | |||||
struct versaloon_pending_t | |||||
{ | |||||
uint8_t type; | |||||
uint8_t cmd; | |||||
uint16_t want_data_pos; | |||||
uint16_t want_data_size; | |||||
uint16_t actual_data_size; | |||||
uint8_t *data_buffer; | |||||
uint8_t collect; | |||||
uint32_t id; | |||||
struct versaloon_want_pos_t *pos; | |||||
void *extra_data; | |||||
versaloon_callback_t callback; | |||||
}; | |||||
extern struct versaloon_pending_t \ | |||||
versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; | |||||
extern uint16_t versaloon_pending_idx; | |||||
void versaloon_set_pending_id(uint32_t id); | |||||
void versaloon_set_callback(versaloon_callback_t callback); | |||||
void versaloon_set_extra_data(void * p); | |||||
RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff); | |||||
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); | |||||
void versaloon_free_want_pos(void); | |||||
RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen); | |||||
extern uint8_t *versaloon_buf; | |||||
extern uint8_t *versaloon_cmd_buf; | |||||
extern uint16_t versaloon_buf_size; | |||||
#endif /* __VERSALOON_INTERNAL_H_INCLUDED__ */ | |||||
@@ -19,7 +19,7 @@ | |||||
/* Versaloon is a programming tool for multiple MCUs. | /* Versaloon is a programming tool for multiple MCUs. | ||||
* It's distributed under GPLv3. | * It's distributed under GPLv3. | ||||
* You can find it at http://www.SimonQian.com/en/Versaloon. | |||||
* You can find it at http://www.Versaloon.com/. | |||||
*/ | */ | ||||
#ifdef HAVE_CONFIG_H | #ifdef HAVE_CONFIG_H | ||||
@@ -30,59 +30,17 @@ | |||||
#include <jtag/commands.h> | #include <jtag/commands.h> | ||||
#include "usb_common.h" | #include "usb_common.h" | ||||
//#define _VSLLINK_IN_DEBUG_MODE_ | |||||
static uint16_t vsllink_usb_vid; | |||||
static uint16_t vsllink_usb_pid; | |||||
static uint8_t vsllink_usb_bulkout; | |||||
static uint8_t vsllink_usb_bulkin; | |||||
static uint8_t vsllink_usb_interface; | |||||
static int VSLLINK_USB_TIMEOUT = 1000; | |||||
#include "versaloon/versaloon_include.h" | |||||
#include "versaloon/versaloon.h" | |||||
static int vsllink_tms_offset; | static int vsllink_tms_offset; | ||||
/* Global USB buffers */ | |||||
static uint8_t *vsllink_usb_in_buffer; | |||||
static uint8_t *vsllink_usb_out_buffer; | |||||
static int vsllink_buffer_size = 128; | |||||
/* Constants for Versaloon command */ | |||||
#define VERSALOON_GET_INFO 0x00 | |||||
#define VERSALOON_GET_TVCC 0x01 | |||||
/* Constants for VSLLink command */ | |||||
#define VSLLINK_CMD_CONN 0x80 | |||||
#define VSLLINK_CMD_DISCONN 0x81 | |||||
#define VSLLINK_CMD_SET_SPEED 0x82 | |||||
#define VSLLINK_CMD_SET_PORT 0x90 | |||||
#define VSLLINK_CMD_GET_PORT 0x91 | |||||
#define VSLLINK_CMD_SET_PORTDIR 0x92 | |||||
#define VSLLINK_CMD_HW_JTAGSEQCMD 0xA0 | |||||
#define VSLLINK_CMD_HW_JTAGHLCMD 0xA1 | |||||
#define VSLLINK_CMD_HW_SWDCMD 0xA2 | |||||
#define VSLLINK_CMD_HW_JTAGRAWCMD 0xA3 | |||||
#define VSLLINK_CMDJTAGSEQ_TMSBYTE 0x00 | |||||
#define VSLLINK_CMDJTAGSEQ_TMSCLOCK 0x40 | |||||
#define VSLLINK_CMDJTAGSEQ_SCAN 0x80 | |||||
#define VSLLINK_CMDJTAGSEQ_CMDMSK 0xC0 | |||||
#define VSLLINK_CMDJTAGSEQ_LENMSK 0x3F | |||||
#define JTAG_PINMSK_SRST (1 << 0) | |||||
#define JTAG_PINMSK_TRST (1 << 1) | |||||
#define JTAG_PINMSK_USR1 (1 << 2) | |||||
#define JTAG_PINMSK_USR2 (1 << 3) | |||||
#define JTAG_PINMSK_TCK (1 << 4) | |||||
#define JTAG_PINMSK_TMS (1 << 5) | |||||
#define JTAG_PINMSK_TDI (1 << 6) | |||||
#define JTAG_PINMSK_TDO (1 << 7) | |||||
struct pending_scan_result { | struct pending_scan_result { | ||||
int src_offset; | int src_offset; | ||||
int dest_offset; | int dest_offset; | ||||
int length; /* Number of bits to read */ | int length; /* Number of bits to read */ | ||||
struct scan_command *command; /* Corresponding scan command */ | struct scan_command *command; /* Corresponding scan command */ | ||||
uint8_t *ack; | |||||
uint8_t *buffer; | uint8_t *buffer; | ||||
bool last; /* indicate the last scan pending */ | bool last; /* indicate the last scan pending */ | ||||
}; | }; | ||||
@@ -97,12 +55,12 @@ static struct pending_scan_result | |||||
static void vsllink_end_state(tap_state_t state); | static void vsllink_end_state(tap_state_t state); | ||||
static void vsllink_state_move(void); | static void vsllink_state_move(void); | ||||
static void vsllink_path_move(int num_states, tap_state_t *path); | static void vsllink_path_move(int num_states, tap_state_t *path); | ||||
static void vsllink_tms(int num_bits, const uint8_t *bits); | |||||
static void vsllink_runtest(int num_cycles); | static void vsllink_runtest(int num_cycles); | ||||
static void vsllink_stableclocks(int num_cycles, int tms); | static void vsllink_stableclocks(int num_cycles, int tms); | ||||
static void vsllink_scan(bool ir_scan, enum scan_type type, | static void vsllink_scan(bool ir_scan, enum scan_type type, | ||||
uint8_t *buffer, int scan_size, struct scan_command *command); | uint8_t *buffer, int scan_size, struct scan_command *command); | ||||
static void vsllink_reset(int trst, int srst); | static void vsllink_reset(int trst, int srst); | ||||
static void vsllink_simple_command(uint8_t command); | |||||
/* VSLLink tap buffer functions */ | /* VSLLink tap buffer functions */ | ||||
static void vsllink_tap_append_step(int tms, int tdi); | static void vsllink_tap_append_step(int tms, int tdi); | ||||
@@ -119,10 +77,6 @@ struct vsllink { | |||||
static struct vsllink *vsllink_usb_open(void); | static struct vsllink *vsllink_usb_open(void); | ||||
static void vsllink_usb_close(struct vsllink *vsllink); | static void vsllink_usb_close(struct vsllink *vsllink); | ||||
static int vsllink_usb_message(struct vsllink *vsllink, int out_length, | |||||
int in_length); | |||||
static int vsllink_usb_write(struct vsllink *vsllink, int out_length); | |||||
static int vsllink_usb_read(struct vsllink *vsllink); | |||||
#if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_ | #if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_ | ||||
static void vsllink_debug_buffer(uint8_t *buffer, int length); | static void vsllink_debug_buffer(uint8_t *buffer, int length); | ||||
@@ -134,12 +88,7 @@ static uint8_t *tms_buffer; | |||||
static uint8_t *tdi_buffer; | static uint8_t *tdi_buffer; | ||||
static uint8_t *tdo_buffer; | static uint8_t *tdo_buffer; | ||||
static struct vsllink *vsllink_handle; | |||||
static void reset_command_pointer(void) | |||||
{ | |||||
tap_length = 0; | |||||
} | |||||
struct vsllink *vsllink_handle; | |||||
static int vsllink_execute_queue(void) | static int vsllink_execute_queue(void) | ||||
{ | { | ||||
@@ -152,7 +101,6 @@ static int vsllink_execute_queue(void) | |||||
" vsllink " | " vsllink " | ||||
"-------------------------------------"); | "-------------------------------------"); | ||||
reset_command_pointer(); | |||||
while (cmd != NULL) { | while (cmd != NULL) { | ||||
switch (cmd->type) { | switch (cmd->type) { | ||||
case JTAG_RUNTEST: | case JTAG_RUNTEST: | ||||
@@ -188,6 +136,8 @@ static int vsllink_execute_queue(void) | |||||
break; | break; | ||||
case JTAG_SCAN: | case JTAG_SCAN: | ||||
DEBUG_JTAG_IO("JTAG Scan..."); | |||||
vsllink_end_state(cmd->cmd.scan->end_state); | vsllink_end_state(cmd->cmd.scan->end_state); | ||||
scan_size = jtag_build_buffer( | scan_size = jtag_build_buffer( | ||||
@@ -244,6 +194,7 @@ static int vsllink_execute_queue(void) | |||||
case JTAG_STABLECLOCKS: | case JTAG_STABLECLOCKS: | ||||
DEBUG_JTAG_IO("add %d clocks", | DEBUG_JTAG_IO("add %d clocks", | ||||
cmd->cmd.stableclocks->num_cycles); | cmd->cmd.stableclocks->num_cycles); | ||||
switch (tap_get_state()) { | switch (tap_get_state()) { | ||||
case TAP_RESET: | case TAP_RESET: | ||||
/* tms must be '1' to stay | /* tms must be '1' to stay | ||||
@@ -271,6 +222,13 @@ static int vsllink_execute_queue(void) | |||||
->num_cycles, scan_size); | ->num_cycles, scan_size); | ||||
break; | break; | ||||
case JTAG_TMS: | |||||
DEBUG_JTAG_IO("add %d jtag tms", | |||||
cmd->cmd.tms->num_bits); | |||||
vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); | |||||
break; | |||||
default: | default: | ||||
LOG_ERROR("BUG: unknown JTAG command type " | LOG_ERROR("BUG: unknown JTAG command type " | ||||
"encountered: %d", cmd->type); | "encountered: %d", cmd->type); | ||||
@@ -284,22 +242,8 @@ static int vsllink_execute_queue(void) | |||||
static int vsllink_speed(int speed) | static int vsllink_speed(int speed) | ||||
{ | { | ||||
int result; | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_SPEED; | |||||
vsllink_usb_out_buffer[1] = (speed >> 0) & 0xff; | |||||
vsllink_usb_out_buffer[2] = (speed >> 8) & 0xFF; | |||||
result = vsllink_usb_write(vsllink_handle, 3); | |||||
if (result == 3) | |||||
return ERROR_OK; | |||||
else { | |||||
LOG_ERROR("VSLLink setting speed failed (%d)", result); | |||||
return ERROR_JTAG_DEVICE_ERROR; | |||||
} | |||||
return ERROR_OK; | |||||
versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed); | |||||
return versaloon_interface.adaptors.peripheral_commit(); | |||||
} | } | ||||
static int vsllink_khz(int khz, int *jtag_speed) | static int vsllink_khz(int khz, int *jtag_speed) | ||||
@@ -316,20 +260,42 @@ static int vsllink_speed_div(int jtag_speed, int *khz) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
static int vsllink_init(void) | |||||
static void vsllink_free_buffer(void) | |||||
{ | { | ||||
int check_cnt, to_tmp; | |||||
int result; | |||||
char version_str[100]; | |||||
vsllink_usb_in_buffer = malloc(vsllink_buffer_size); | |||||
vsllink_usb_out_buffer = malloc(vsllink_buffer_size); | |||||
if ((vsllink_usb_in_buffer == NULL) | |||||
|| (vsllink_usb_out_buffer == NULL)) { | |||||
LOG_ERROR("Not enough memory"); | |||||
exit(-1); | |||||
if (tdi_buffer != NULL) | |||||
{ | |||||
free(tdi_buffer); | |||||
tdi_buffer = NULL; | |||||
} | |||||
if (tdo_buffer != NULL) | |||||
{ | |||||
free(tdo_buffer); | |||||
tdo_buffer = NULL; | |||||
} | |||||
if (tms_buffer != NULL) | |||||
{ | |||||
free(tms_buffer); | |||||
tms_buffer = NULL; | |||||
} | } | ||||
} | |||||
static int vsllink_quit(void) | |||||
{ | |||||
versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST, | |||||
0, 0, GPIO_SRST | GPIO_TRST); | |||||
versaloon_interface.adaptors.gpio.fini(0); | |||||
versaloon_interface.adaptors.jtag_raw.fini(0); | |||||
versaloon_interface.adaptors.peripheral_commit(); | |||||
versaloon_interface.fini(); | |||||
vsllink_free_buffer(); | |||||
vsllink_usb_close(vsllink_handle); | |||||
return ERROR_OK; | |||||
} | |||||
static int vsllink_init(void) | |||||
{ | |||||
vsllink_handle = vsllink_usb_open(); | vsllink_handle = vsllink_usb_open(); | ||||
if (vsllink_handle == 0) { | if (vsllink_handle == 0) { | ||||
LOG_ERROR("Can't find USB JTAG Interface!"\ | LOG_ERROR("Can't find USB JTAG Interface!"\ | ||||
@@ -337,131 +303,44 @@ static int vsllink_init(void) | |||||
return ERROR_JTAG_INIT_FAILED; | return ERROR_JTAG_INIT_FAILED; | ||||
} | } | ||||
LOG_DEBUG("vsllink found on %04X:%04X", | LOG_DEBUG("vsllink found on %04X:%04X", | ||||
vsllink_usb_vid, vsllink_usb_pid); | |||||
to_tmp = VSLLINK_USB_TIMEOUT; | |||||
VSLLINK_USB_TIMEOUT = 100; | |||||
check_cnt = 0; | |||||
while (check_cnt < 5) { | |||||
vsllink_simple_command(VERSALOON_GET_INFO); | |||||
result = vsllink_usb_read(vsllink_handle); | |||||
if (result > 2) { | |||||
vsllink_usb_in_buffer[result] = 0; | |||||
vsllink_buffer_size = vsllink_usb_in_buffer[0] | |||||
+ (vsllink_usb_in_buffer[1] << 8); | |||||
strncpy(version_str, (char *)vsllink_usb_in_buffer + 2, | |||||
sizeof(version_str)); | |||||
LOG_INFO("%s", version_str); | |||||
/* free the pre-allocated memory */ | |||||
free(vsllink_usb_in_buffer); | |||||
free(vsllink_usb_out_buffer); | |||||
vsllink_usb_in_buffer = NULL; | |||||
vsllink_usb_out_buffer = NULL; | |||||
/* alloc new memory */ | |||||
vsllink_usb_in_buffer = malloc(vsllink_buffer_size); | |||||
vsllink_usb_out_buffer = malloc(vsllink_buffer_size); | |||||
if ((vsllink_usb_in_buffer == NULL) || | |||||
(vsllink_usb_out_buffer == NULL)) { | |||||
LOG_ERROR("Not enough memory"); | |||||
exit(-1); | |||||
} else | |||||
LOG_INFO("buffer size for USB is %d bytes", | |||||
vsllink_buffer_size); | |||||
/* alloc tms/tdi/tdo buffer */ | |||||
tap_buffer_size = (vsllink_buffer_size - 3) / 2; | |||||
tms_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
tdi_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
tdo_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
if ((tms_buffer == NULL) || (tdi_buffer == NULL) || | |||||
(tdo_buffer == NULL)) { | |||||
LOG_ERROR("Not enough memory"); | |||||
exit(-1); | |||||
} | |||||
break; | |||||
} | |||||
vsllink_simple_command(VSLLINK_CMD_DISCONN); | |||||
check_cnt++; | |||||
versaloon_interface.usb_setting.vid, | |||||
versaloon_interface.usb_setting.pid); | |||||
versaloon_usb_device_handle = vsllink_handle->usb_handle; | |||||
if (ERROR_OK != versaloon_interface.init()) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | } | ||||
if (check_cnt == 3) { | |||||
/* Fail to access Versaloon */ | |||||
LOG_ERROR("VSLLink initial failed"); | |||||
exit(-1); | |||||
if (versaloon_interface.usb_setting.buf_size < 32) | |||||
{ | |||||
versaloon_interface.fini(); | |||||
return ERROR_FAIL; | |||||
} | } | ||||
VSLLINK_USB_TIMEOUT = to_tmp; | |||||
/* Some older firmware versions sometimes fail if the | |||||
* voltage isn't read first. | |||||
*/ | |||||
vsllink_simple_command(VERSALOON_GET_TVCC); | |||||
result = vsllink_usb_read(vsllink_handle); | |||||
if (result != 2) | |||||
LOG_WARNING("Fail to get target voltage"); | |||||
else | |||||
LOG_INFO("Target runs at %d mV", vsllink_usb_in_buffer[0] + | |||||
(vsllink_usb_in_buffer[1] << 8)); | |||||
/* connect to vsllink */ | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_CONN; | |||||
vsllink_usb_out_buffer[1] = 1; | |||||
vsllink_usb_message(vsllink_handle, 2, 0); | |||||
if (vsllink_usb_read(vsllink_handle) > 2) { | |||||
strncpy(version_str, (char *)vsllink_usb_in_buffer + 2, | |||||
sizeof(version_str)); | |||||
LOG_INFO("%s", version_str); | |||||
// malloc buffer size for tap | |||||
tap_buffer_size = versaloon_interface.usb_setting.buf_size - 32; | |||||
vsllink_free_buffer(); | |||||
tdi_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
tdo_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
tms_buffer = (uint8_t *)malloc(tap_buffer_size); | |||||
if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer)) | |||||
{ | |||||
vsllink_quit(); | |||||
return ERROR_FAIL; | |||||
} | } | ||||
/* Set SRST and TRST to output, Set USR1 and USR2 to input */ | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR; | |||||
vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST | |||||
| JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2; | |||||
vsllink_usb_out_buffer[2] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST; | |||||
if (vsllink_usb_write(vsllink_handle, 3) != 3) { | |||||
LOG_ERROR("VSLLink USB send data error"); | |||||
exit(-1); | |||||
versaloon_interface.adaptors.jtag_raw.init(0); | |||||
versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz()); | |||||
versaloon_interface.adaptors.gpio.init(0); | |||||
versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST, | |||||
GPIO_TRST, GPIO_SRST, GPIO_SRST); | |||||
if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit()) | |||||
{ | |||||
return ERROR_FAIL; | |||||
} | } | ||||
vsllink_reset(0, 0); | vsllink_reset(0, 0); | ||||
LOG_INFO("VSLLink Interface ready"); | |||||
vsllink_tap_init(); | vsllink_tap_init(); | ||||
return ERROR_OK; | |||||
} | |||||
static int vsllink_quit(void) | |||||
{ | |||||
if ((vsllink_usb_in_buffer != NULL) | |||||
&& (vsllink_usb_out_buffer != NULL)) { | |||||
// Set all pins to input | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR; | |||||
vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST | |||||
| JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2; | |||||
vsllink_usb_out_buffer[2] = 0; | |||||
if (vsllink_usb_write(vsllink_handle, 3) != 3) { | |||||
LOG_ERROR("VSLLink USB send data error"); | |||||
exit(-1); | |||||
} | |||||
// disconnect | |||||
vsllink_simple_command(VSLLINK_CMD_DISCONN); | |||||
vsllink_usb_close(vsllink_handle); | |||||
vsllink_handle = NULL; | |||||
} | |||||
if (vsllink_usb_in_buffer != NULL) { | |||||
free(vsllink_usb_in_buffer); | |||||
vsllink_usb_in_buffer = NULL; | |||||
} | |||||
if (vsllink_usb_out_buffer != NULL) { | |||||
free(vsllink_usb_out_buffer); | |||||
vsllink_usb_out_buffer = NULL; | |||||
} | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -513,6 +392,13 @@ static void vsllink_path_move(int num_states, tap_state_t *path) | |||||
tap_set_end_state(tap_get_state()); | tap_set_end_state(tap_get_state()); | ||||
} | } | ||||
static void vsllink_tms(int num_bits, const uint8_t *bits) | |||||
{ | |||||
for (int i = 0; i < num_bits; i++) { | |||||
vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0); | |||||
} | |||||
} | |||||
static void vsllink_stableclocks(int num_cycles, int tms) | static void vsllink_stableclocks(int num_cycles, int tms) | ||||
{ | { | ||||
while (num_cycles > 0) { | while (num_cycles > 0) { | ||||
@@ -569,48 +455,18 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, | |||||
static void vsllink_reset(int trst, int srst) | static void vsllink_reset(int trst, int srst) | ||||
{ | { | ||||
int result; | |||||
LOG_DEBUG("trst: %i, srst: %i", trst, srst); | LOG_DEBUG("trst: %i, srst: %i", trst, srst); | ||||
/* Signals are active low */ | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORT; | |||||
vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST; | |||||
vsllink_usb_out_buffer[2] = 0; | |||||
if (srst == 0) | |||||
vsllink_usb_out_buffer[2] |= JTAG_PINMSK_SRST; | |||||
if (trst == 0) | |||||
vsllink_usb_out_buffer[2] |= JTAG_PINMSK_TRST; | |||||
result = vsllink_usb_write(vsllink_handle, 3); | |||||
if (result != 3) | |||||
LOG_ERROR("VSLLink command VSLLINK_CMD_SET_PORT failed (%d)", | |||||
result); | |||||
} | |||||
static void vsllink_simple_command(uint8_t command) | |||||
{ | |||||
int result; | |||||
DEBUG_JTAG_IO("0x%02x", command); | |||||
vsllink_usb_out_buffer[0] = command; | |||||
result = vsllink_usb_write(vsllink_handle, 1); | |||||
if (result != 1) | |||||
LOG_ERROR("VSLLink command 0x%02x failed (%d)", | |||||
command, result); | |||||
} | |||||
COMMAND_HANDLER(vsllink_handle_mode_command) | |||||
{ | |||||
if (CMD_ARGC != 1) { | |||||
LOG_ERROR("parameter error, " | |||||
"should be one parameter for mode"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (!srst) | |||||
versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST); | |||||
else | |||||
versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0); | |||||
return ERROR_OK; | |||||
if (!trst) | |||||
versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST); | |||||
else | |||||
versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0); | |||||
versaloon_interface.adaptors.peripheral_commit(); | |||||
} | } | ||||
COMMAND_HANDLER(vsllink_handle_usb_vid_command) | COMMAND_HANDLER(vsllink_handle_usb_vid_command) | ||||
@@ -621,7 +477,8 @@ COMMAND_HANDLER(vsllink_handle_usb_vid_command) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_vid); | |||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], | |||||
versaloon_interface.usb_setting.vid); | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -632,7 +489,8 @@ COMMAND_HANDLER(vsllink_handle_usb_pid_command) | |||||
"should be one parameter for PID"); | "should be one parameter for PID"); | ||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_pid); | |||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], | |||||
versaloon_interface.usb_setting.pid); | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -644,9 +502,10 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkin_command) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkin); | |||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], | |||||
versaloon_interface.usb_setting.ep_in); | |||||
vsllink_usb_bulkin |= 0x80; | |||||
versaloon_interface.usb_setting.ep_in |= 0x80; | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -659,9 +518,10 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkout_command) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkout); | |||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], | |||||
versaloon_interface.usb_setting.ep_out); | |||||
vsllink_usb_bulkout &= ~0x80; | |||||
versaloon_interface.usb_setting.ep_out &= ~0x80; | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -674,7 +534,8 @@ COMMAND_HANDLER(vsllink_handle_usb_interface_command) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_interface); | |||||
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], | |||||
versaloon_interface.usb_setting.interface); | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -760,94 +621,20 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer, | |||||
} | } | ||||
} | } | ||||
static int vsllink_tap_execute(void) | |||||
static int vsllink_jtag_execute(void) | |||||
{ | { | ||||
int byte_length; | |||||
int i; | int i; | ||||
int result; | int result; | ||||
if (tap_length <= 0) | if (tap_length <= 0) | ||||
return ERROR_OK; | return ERROR_OK; | ||||
/* Pad data so that tap_length is divisible by 8 */ | |||||
if ((tap_length % 8) != 0) { | |||||
if (vsllink_tms_offset > 0) { | |||||
/* append tms:0 at vsllink_tms_offset, | |||||
* which is in Pause | |||||
*/ | |||||
int start_pos = DIV_ROUND_UP(tap_length, 8) - 1; | |||||
int end_pos = DIV_ROUND_UP(vsllink_tms_offset, 8) - 1; | |||||
int shift_cnt = (start_pos + 1) * 8 - tap_length; | |||||
uint8_t last_mask = ~( | |||||
(1 << (vsllink_tms_offset % 8)) - 1); | |||||
while (1) { | |||||
if (start_pos == end_pos) { | |||||
tms_buffer[start_pos] = | |||||
(tms_buffer[start_pos] | |||||
& ~last_mask) | |||||
| ((tms_buffer[start_pos] | |||||
& last_mask) | |||||
<< shift_cnt); | |||||
tdi_buffer[start_pos] = | |||||
(tdi_buffer[start_pos] | |||||
& ~last_mask) | |||||
| | |||||
((tdi_buffer[start_pos] | |||||
& last_mask) | |||||
<< shift_cnt); | |||||
break; | |||||
} else if (start_pos == (end_pos + 1)) { | |||||
tms_buffer[start_pos] = | |||||
(tms_buffer[start_pos] | |||||
<< shift_cnt) | | |||||
((tms_buffer[start_pos - 1] | |||||
& last_mask) | |||||
>> (8 - shift_cnt)); | |||||
tdi_buffer[start_pos] = | |||||
(tdi_buffer[start_pos] | |||||
<< shift_cnt) | | |||||
((tdi_buffer[start_pos - 1] | |||||
& last_mask) | |||||
>> (8 - shift_cnt)); | |||||
} else { | |||||
tms_buffer[start_pos] = | |||||
(tms_buffer[start_pos] | |||||
<< shift_cnt) | | |||||
(tms_buffer[start_pos - 1] | |||||
>> (8 - shift_cnt)); | |||||
tdi_buffer[start_pos] = | |||||
(tdi_buffer[start_pos] | |||||
<< shift_cnt) | | |||||
(tdi_buffer[start_pos - 1] | |||||
>> (8 - shift_cnt)); | |||||
} | |||||
start_pos--; | |||||
} | |||||
tap_length = DIV_ROUND_UP(tap_length, 8) * 8; | |||||
} else { | |||||
/* append data at last */ | |||||
while ((tap_length % 8) != 0) { | |||||
vsllink_tap_append_step( | |||||
(tap_get_state() == TAP_RESET) | |||||
? 1 : 0, 0); | |||||
} | |||||
} | |||||
} | |||||
byte_length = tap_length / 8; | |||||
vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGRAWCMD; | |||||
vsllink_usb_out_buffer[1] = ((byte_length * 2 + 3) >> 0) & 0xff; | |||||
vsllink_usb_out_buffer[2] = ((byte_length * 2 + 3) >> 8) & 0xff; | |||||
versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer, | |||||
tdo_buffer, tap_length); | |||||
memcpy(&vsllink_usb_out_buffer[3], tdi_buffer, byte_length); | |||||
memcpy(&vsllink_usb_out_buffer[3 + byte_length], tms_buffer, | |||||
byte_length); | |||||
result = versaloon_interface.adaptors.peripheral_commit(); | |||||
result = vsllink_usb_message(vsllink_handle, 3 + 2 * byte_length, | |||||
byte_length); | |||||
if (result == byte_length) { | |||||
if (result == ERROR_OK) { | |||||
for (i = 0; i < pending_scan_results_length; i++) { | for (i = 0; i < pending_scan_results_length; i++) { | ||||
struct pending_scan_result *pending_scan_result = | struct pending_scan_result *pending_scan_result = | ||||
&pending_scan_results_buffer[i]; | &pending_scan_results_buffer[i]; | ||||
@@ -860,12 +647,12 @@ static int vsllink_tap_execute(void) | |||||
struct scan_command *command; | struct scan_command *command; | ||||
command = pending_scan_result->command; | command = pending_scan_result->command; | ||||
buf_set_buf(vsllink_usb_in_buffer, src_first, buffer, | |||||
dest_first, length); | |||||
buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length); | |||||
DEBUG_JTAG_IO("JTAG scan read(%d bits, from %d bits):", | |||||
length, dest_first); | |||||
#ifdef _DEBUG_JTAG_IO_ | #ifdef _DEBUG_JTAG_IO_ | ||||
DEBUG_JTAG_IO( | |||||
"JTAG scan read(%d bits, from src %d bits to dest %d bits):", | |||||
length, src_first, dest_first); | |||||
vsllink_debug_buffer(buffer + dest_first / 8, | vsllink_debug_buffer(buffer + dest_first / 8, | ||||
DIV_ROUND_UP(length, 7)); | DIV_ROUND_UP(length, 7)); | ||||
#endif | #endif | ||||
@@ -882,8 +669,7 @@ static int vsllink_tap_execute(void) | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
LOG_ERROR("vsllink_tap_execute, wrong result %d, expected %d", | |||||
result, byte_length); | |||||
LOG_ERROR("vsllink_jtag_execute failure"); | |||||
return ERROR_JTAG_QUEUE_FAILED; | return ERROR_JTAG_QUEUE_FAILED; | ||||
} | } | ||||
@@ -892,42 +678,131 @@ static int vsllink_tap_execute(void) | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
static int vsllink_tap_execute(void) | |||||
{ | |||||
return vsllink_jtag_execute(); | |||||
} | |||||
/*****************************************************************************/ | /*****************************************************************************/ | ||||
/* VSLLink USB low-level functions */ | /* VSLLink USB low-level functions */ | ||||
static uint8_t usb_check_string(usb_dev_handle *usb, uint8_t stringidx, | |||||
char * string, char * buff, uint16_t buf_size) | |||||
{ | |||||
int len; | |||||
uint8_t alloced = 0; | |||||
uint8_t ret = 1; | |||||
if (NULL == buff) | |||||
{ | |||||
buf_size = 256; | |||||
buff = (char*)malloc(buf_size); | |||||
if (NULL == buff) | |||||
{ | |||||
ret = 0; | |||||
goto free_and_return; | |||||
} | |||||
alloced = 1; | |||||
} | |||||
strcpy(buff, ""); | |||||
len = usb_get_string_simple(usb, stringidx, (char *)buff, buf_size); | |||||
if ((len < 0) || (len != ((int)strlen((const char *)buff)))) | |||||
{ | |||||
ret = 0; | |||||
goto free_and_return; | |||||
} | |||||
buff[len] = '\0'; | |||||
if ((string != NULL) && strcmp((const char *)buff, string)) | |||||
{ | |||||
ret = 0; | |||||
goto free_and_return; | |||||
} | |||||
free_and_return: | |||||
if (alloced && (buff != NULL)) | |||||
{ | |||||
free(buff); | |||||
buff = NULL; | |||||
} | |||||
return ret; | |||||
} | |||||
static usb_dev_handle* find_usb_device(uint16_t VID, uint16_t PID, | |||||
uint8_t interface, int8_t serialindex, char *serialstring, | |||||
int8_t productindex, char *productstring) | |||||
{ | |||||
usb_dev_handle *dev_handle = NULL; | |||||
struct usb_bus *busses; | |||||
struct usb_bus *bus; | |||||
struct usb_device *dev; | |||||
usb_init(); | |||||
usb_find_busses(); | |||||
usb_find_devices(); | |||||
busses = usb_get_busses(); | |||||
for (bus = busses; bus; bus = bus->next) | |||||
{ | |||||
for (dev = bus->devices; dev; dev = dev->next) | |||||
{ | |||||
if ((dev->descriptor.idVendor == VID) | |||||
&& (dev->descriptor.idProduct == PID)) | |||||
{ | |||||
dev_handle = usb_open(dev); | |||||
if (NULL == dev_handle) | |||||
{ | |||||
LOG_ERROR("failed to open %04X:%04X, %s", VID, PID, | |||||
usb_strerror()); | |||||
continue; | |||||
} | |||||
// check description string | |||||
if (((productstring != NULL) && (productindex >= 0) | |||||
&& !usb_check_string(dev_handle, productindex, | |||||
productstring, NULL, 0)) | |||||
|| ((serialstring != NULL) && (serialindex >= 0) | |||||
&& !usb_check_string(dev_handle, serialindex, | |||||
serialstring, NULL, 0))) | |||||
{ | |||||
usb_close(dev_handle); | |||||
dev_handle = NULL; | |||||
continue; | |||||
} | |||||
if (usb_claim_interface(dev_handle, interface) != 0) | |||||
{ | |||||
LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE, | |||||
"claim interface", usb_strerror()); | |||||
usb_close(dev_handle); | |||||
dev_handle = NULL; | |||||
continue; | |||||
} | |||||
if (dev_handle != NULL) | |||||
{ | |||||
return dev_handle; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return dev_handle; | |||||
} | |||||
static struct vsllink *vsllink_usb_open(void) | static struct vsllink *vsllink_usb_open(void) | ||||
{ | { | ||||
usb_init(); | usb_init(); | ||||
const uint16_t vids[] = { vsllink_usb_vid, 0 }; | |||||
const uint16_t pids[] = { vsllink_usb_pid, 0 }; | |||||
struct usb_dev_handle *dev; | struct usb_dev_handle *dev; | ||||
if (jtag_usb_open(vids, pids, &dev) != ERROR_OK) | |||||
return NULL; | |||||
/* usb_set_configuration required under win32 */ | |||||
struct usb_device *udev = usb_device(dev); | |||||
int ret = usb_set_configuration(dev, | |||||
udev->config[0].bConfigurationValue); | |||||
if (ret != 0) { | |||||
LOG_ERROR("fail to set configuration to %d (error %d)." | |||||
"Not enough permissions for the device?", | |||||
udev->config[0].bConfigurationValue, ret); | |||||
return NULL; | |||||
} | |||||
ret = usb_claim_interface(dev, vsllink_usb_interface); | |||||
if (ret != 0) { | |||||
LOG_ERROR("fail to claim interface %d, %d returned", | |||||
vsllink_usb_interface, ret); | |||||
dev = find_usb_device(versaloon_interface.usb_setting.vid, | |||||
versaloon_interface.usb_setting.pid, | |||||
versaloon_interface.usb_setting.interface, | |||||
0, NULL, 2, "Versaloon"); | |||||
if (NULL == dev) | |||||
return NULL; | return NULL; | ||||
} | |||||
#if 0 | |||||
/* | |||||
* This makes problems under Mac OS X. And is not needed | |||||
* under Windows. Hopefully this will not break a linux build | |||||
*/ | |||||
usb_set_altinterface(dev, 0); | |||||
#endif | |||||
struct vsllink *result = malloc(sizeof(struct vsllink)); | struct vsllink *result = malloc(sizeof(struct vsllink)); | ||||
result->usb_handle = dev; | result->usb_handle = dev; | ||||
@@ -939,10 +814,10 @@ static void vsllink_usb_close(struct vsllink *vsllink) | |||||
int ret; | int ret; | ||||
ret = usb_release_interface(vsllink->usb_handle, | ret = usb_release_interface(vsllink->usb_handle, | ||||
vsllink_usb_interface); | |||||
versaloon_interface.usb_setting.interface); | |||||
if (ret != 0) { | if (ret != 0) { | ||||
LOG_ERROR("fail to release interface %d, %d returned", | LOG_ERROR("fail to release interface %d, %d returned", | ||||
vsllink_usb_interface, ret); | |||||
versaloon_interface.usb_setting.interface, ret); | |||||
exit(-1); | exit(-1); | ||||
} | } | ||||
@@ -955,79 +830,6 @@ static void vsllink_usb_close(struct vsllink *vsllink) | |||||
free(vsllink); | free(vsllink); | ||||
} | } | ||||
/* Send a message and receive the reply. */ | |||||
static int vsllink_usb_message(struct vsllink *vsllink, int out_length, | |||||
int in_length) | |||||
{ | |||||
int result; | |||||
result = vsllink_usb_write(vsllink, out_length); | |||||
if (result == out_length) { | |||||
if (in_length > 0) { | |||||
result = vsllink_usb_read(vsllink); | |||||
if (result == in_length) | |||||
return result; | |||||
else { | |||||
LOG_ERROR("usb_bulk_read failed " | |||||
"(requested=%d, result=%d)", | |||||
in_length, result); | |||||
return -1; | |||||
} | |||||
} | |||||
return 0; | |||||
} else { | |||||
LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", | |||||
out_length, result); | |||||
return -1; | |||||
} | |||||
} | |||||
/* Write data from out_buffer to USB. */ | |||||
static int vsllink_usb_write(struct vsllink *vsllink, int out_length) | |||||
{ | |||||
int result; | |||||
if (out_length > vsllink_buffer_size) { | |||||
LOG_ERROR("vsllink_write illegal out_length=%d (max=%d)", | |||||
out_length, vsllink_buffer_size); | |||||
return -1; | |||||
} | |||||
result = usb_bulk_write(vsllink->usb_handle, vsllink_usb_bulkout, | |||||
(char *)vsllink_usb_out_buffer, out_length, | |||||
VSLLINK_USB_TIMEOUT); | |||||
DEBUG_JTAG_IO("vsllink_usb_write, out_length = %d, result = %d", | |||||
out_length, result); | |||||
#ifdef _DEBUG_USB_COMMS_ | |||||
LOG_DEBUG("USB out:"); | |||||
vsllink_debug_buffer(vsllink_usb_out_buffer, out_length); | |||||
#endif | |||||
#ifdef _VSLLINK_IN_DEBUG_MODE_ | |||||
usleep(100000); | |||||
#endif | |||||
return result; | |||||
} | |||||
/* Read data from USB into in_buffer. */ | |||||
static int vsllink_usb_read(struct vsllink *vsllink) | |||||
{ | |||||
int result = usb_bulk_read(vsllink->usb_handle, vsllink_usb_bulkin, | |||||
(char *)vsllink_usb_in_buffer, vsllink_buffer_size, | |||||
VSLLINK_USB_TIMEOUT); | |||||
DEBUG_JTAG_IO("vsllink_usb_read, result = %d", result); | |||||
#ifdef _DEBUG_USB_COMMS_ | |||||
LOG_DEBUG("USB in:"); | |||||
vsllink_debug_buffer(vsllink_usb_in_buffer, result); | |||||
#endif | |||||
return result; | |||||
} | |||||
#define BYTES_PER_LINE 16 | #define BYTES_PER_LINE 16 | ||||
#if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_ | #if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_ | ||||
@@ -1075,17 +877,16 @@ static const struct command_registration vsllink_command_handlers[] = { | |||||
.handler = &vsllink_handle_usb_interface_command, | .handler = &vsllink_handle_usb_interface_command, | ||||
.mode = COMMAND_CONFIG, | .mode = COMMAND_CONFIG, | ||||
}, | }, | ||||
{ | |||||
.name = "vsllink_mode", | |||||
.handler = &vsllink_handle_mode_command, | |||||
.mode = COMMAND_CONFIG, | |||||
}, | |||||
COMMAND_REGISTRATION_DONE | COMMAND_REGISTRATION_DONE | ||||
}; | }; | ||||
static const char *vsllink_transports[] = {"jtag", "swd", NULL}; | |||||
struct jtag_interface vsllink_interface = { | struct jtag_interface vsllink_interface = { | ||||
.name = "vsllink", | .name = "vsllink", | ||||
.supported = DEBUG_CAP_TMS_SEQ, | |||||
.commands = vsllink_command_handlers, | .commands = vsllink_command_handlers, | ||||
.transports = vsllink_transports, | |||||
.init = vsllink_init, | .init = vsllink_init, | ||||
.quit = vsllink_quit, | .quit = vsllink_quit, | ||||
@@ -1,25 +1,8 @@ | |||||
# | # | ||||
# Versaloon Link -- VSLLink | # Versaloon Link -- VSLLink | ||||
# | # | ||||
# http://www.simonqian.com/en/Versaloon | |||||
# http://www.versaloon.com/ | |||||
# | # | ||||
interface vsllink | interface vsllink | ||||
#vsllink_usb_vid 0x03EB | |||||
#vsllink_usb_pid 0x2103 | |||||
#vsllink_usb_bulkin 0x02 | |||||
#vsllink_usb_bulkout 0x02 | |||||
#vsllink_usb_interface 0 | |||||
vsllink_usb_vid 0x0483 | |||||
vsllink_usb_pid 0x5740 | |||||
vsllink_usb_bulkin 0x02 | |||||
vsllink_usb_bulkout 0x03 | |||||
vsllink_usb_interface 1 | |||||
# vsllink mode, dma or normal | |||||
# for low adapter_khz, use normal | |||||
# for high adapter_khz, use dma | |||||
#vsllink_mode dma | |||||
vsllink_mode normal |