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 | |||
endif | |||
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 | |||
endif | |||
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 * | |||