New driver: load-bsl.

This driver supports the USB bootstrap loader. An initial version query
is performed on startup. If the running loader is not sufficiently
featureful, a software image for an upgraded BSL is loaded into the
chip's RAM and executed.
This commit is contained in:
Daniel Beer 2013-07-18 14:00:04 +12:00
parent b407fca15e
commit d3b57a5cd7
9 changed files with 1295 additions and 3 deletions

View File

@ -124,6 +124,7 @@ OBJ=\
transport/rf2500.o \ transport/rf2500.o \
transport/ti3410.o \ transport/ti3410.o \
transport/comport.o \ transport/comport.o \
transport/bslhid.o \
drivers/device.o \ drivers/device.o \
drivers/bsl.o \ drivers/bsl.o \
drivers/fet.o \ drivers/fet.o \
@ -142,6 +143,8 @@ OBJ=\
drivers/jtdev.o \ drivers/jtdev.o \
drivers/jtaglib.o \ drivers/jtaglib.o \
drivers/pif.o \ drivers/pif.o \
drivers/loadbsl.o \
drivers/loadbsl_fw.o \
formats/binfile.o \ formats/binfile.o \
formats/coff.o \ formats/coff.o \
formats/elf32.o \ formats/elf32.o \

461
drivers/loadbsl.c Normal file
View File

@ -0,0 +1,461 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2013 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <string.h>
#include "output.h"
#include "util.h"
#include "loadbsl.h"
#include "loadbsl_fw.h"
#include "bslhid.h"
#define BSL_MAX_CORE 62
#define BSL_MAX_BLOCK 52
#define BSL_CMD_RX_BLOCK 0x10
#define BSL_CMD_RX_BLOCK_FAST 0x1B
#define BSL_CMD_RX_PASSWORD 0x11
#define BSL_CMD_ERASE_SEGMENT 0x12
#define BSL_CMD_UNLOCK_LOCK_INFO 0x13
#define BSL_CMD_MASS_ERASE 0x15
#define BSL_CMD_CRC_CHECK 0x16
#define BSL_CMD_LOAD_PC 0x17
#define BSL_CMD_TX_BLOCK 0x18
#define BSL_CMD_TX_VERSION 0x19
#define BSL_CMD_TX_BUFSIZE 0x1A
#define BSL_PACKET_HEADER 0x80
#define BSL_PACKET_ACK 0x90
/* BSL error codes: from SLAU319C ("MSP430 Programming via the Bootstrap
* Loader").
*/
static const char *const bsl_error_table[9] = {
[0x00] = "Success",
[0x01] = "Flash write check failed",
[0x02] = "Flash fail bit set",
[0x03] = "Voltage change during program",
[0x04] = "BSL locked",
[0x05] = "BSL password error",
[0x06] = "Byte write forbidden",
[0x07] = "Unknown command",
[0x08] = "Packet length exceeds buffer size"
};
static const char *bsl_error_message(int code)
{
const char *text = NULL;
if (code >= 0 && code < ARRAY_LEN(bsl_error_table))
text = bsl_error_table[code];
if (text)
return text;
return "Unknown error code";
}
struct loadbsl_device {
struct device base;
transport_t trans;
};
static int send_command(transport_t trans, uint8_t cmd,
address_t addr, const uint8_t *data, int datalen)
{
uint8_t outbuf[BSL_MAX_CORE];
const int addrlen = (addr != ADDRESS_NONE) ? 3 : 0;
const int corelen = datalen + addrlen + 1;
if (datalen > BSL_MAX_BLOCK) {
printc_err("loadbsl: send_command: MAX_BLOCK exceeded: %d\n",
datalen);
return -1;
}
outbuf[0] = cmd;
if (addrlen > 0) {
outbuf[1] = addr & 0xff;
outbuf[2] = (addr >> 8) & 0xff;
outbuf[3] = (addr >> 16) & 0xff;
}
memcpy(outbuf + 1 + addrlen, data, datalen);
if (trans->ops->send(trans, outbuf, corelen) < 0) {
printc_err("loadbsl: send_command failed\n");
return -1;
}
return 0;
}
static int recv_packet(transport_t trans, uint8_t *data, int max_len)
{
uint8_t inbuf[BSL_MAX_CORE];
int len = trans->ops->recv(trans, inbuf, sizeof(inbuf));
int type;
int code;
if (len < 0) {
printc_err("loadbsl: recv_packet: transport error\n");
return -1;
}
if (len < 1) {
printc_err("loadbsl: recv_packet: zero-length packet\n");
return -1;
}
type = inbuf[0];
if (type == 0x3a) {
const int data_len = len - 1;
if (!data)
return 0;
if (data_len > max_len) {
printc_err("loadbsl: recv_packet: packet too "
"long for buffer (%d bytes)\n", data_len);
return -1;
}
memcpy(data, inbuf + 1, data_len);
return data_len;
}
if (type != 0x3b) {
printc_err("loadbsl: recv_packet: unknown packet type: "
"0x%02x\n", type);
return -1;
}
if (len < 2) {
printc_err("loadbsl: recv_packet: missing response code\n");
return -1;
}
code = inbuf[1];
if (code) {
printc_err("loadbsl: recv_packet: BSL error code: %d (%s)\n",
code, bsl_error_message(code));
return -1;
}
return 0;
}
/* Retrieve and display BSL version info. Returns API version byte. */
static int version_check(transport_t trans)
{
uint8_t data[4];
int r;
if (send_command(trans, BSL_CMD_TX_VERSION,
ADDRESS_NONE, NULL, 0) < 0) {
printc_err("loadbsl: failed to send TX_VERSION command\n");
return -1;
}
r = recv_packet(trans, data, 4);
if (r < 0) {
printc_err("loadbsl: failed to receive version\n");
return -1;
}
if (r < 4) {
printc_err("loadbsl: short version response\n");
return -1;
}
printc_dbg("BSL version: [vendor: %02x, int: %02x, "
"API: %02x, per: %02x]\n",
data[0], data[1], data[2], data[3]);
return data[2];
}
static int do_writemem(transport_t trans,
address_t addr, const uint8_t *mem, address_t len)
{
while (len) {
int plen = len;
if (plen > BSL_MAX_BLOCK)
plen = BSL_MAX_BLOCK;
if (send_command(trans, BSL_CMD_RX_BLOCK_FAST,
addr, mem, plen) < 0) {
printc_err("loadbsl: failed to write block "
"to 0x%04x\n", addr);
return -1;
}
addr += plen;
mem += plen;
len -= plen;
}
return 0;
}
static int rx_password(transport_t trans)
{
uint8_t password[32];
memset(password, 0xff, sizeof(password));
if (send_command(trans, BSL_CMD_RX_PASSWORD, ADDRESS_NONE,
password, sizeof(password)) < 0 ||
recv_packet(trans, NULL, 0) < 0) {
printc_err("loadbsl: rx_password failed\n");
return -1;
}
return 0;
}
static int check_and_load(transport_t trans)
{
const struct loadbsl_fw *fw = &loadbsl_fw_usb5xx;
int api_version = version_check(trans);
if ((api_version >= 0) && (api_version != 0x80))
return 0;
printc_dbg("Uploading BSL firmware (%d bytes at address 0x%04x)...\n",
fw->size, fw->prog_addr);
if (do_writemem(trans, fw->prog_addr, fw->data, fw->size) < 0) {
printc_err("loadbsl: firmware upload failed\n");
return -1;
}
printc_dbg("Starting new firmware (PC: 0x%04x)...\n", fw->entry_point);
if (send_command(trans, BSL_CMD_LOAD_PC, fw->entry_point,
NULL, 0) < 0) {
printc_err("loadbsl: PC load failed\n");
return -1;
}
if (trans->ops->suspend && trans->ops->resume &&
trans->ops->suspend(trans) < 0) {
printc_err("loadbsl: transport suspend failed\n");
return -1;
}
printc_dbg("Done, waiting for startup\n");
delay_ms(1000);
if (trans->ops->suspend && trans->ops->resume &&
trans->ops->resume(trans) < 0) {
printc_err("loadbsl: transport resume failed\n");
return -1;
}
if (rx_password(trans) < 0) {
printc_err("loadbsl: failed to unlock new firmware\n");
return -1;
}
return version_check(trans);
}
static void loadbsl_destroy(device_t base)
{
struct loadbsl_device *dev = (struct loadbsl_device *)base;
dev->trans->ops->destroy(dev->trans);
free(dev);
}
static int loadbsl_readmem(device_t base, address_t addr,
uint8_t *mem, address_t len)
{
struct loadbsl_device *dev = (struct loadbsl_device *)base;
while (len) {
int plen = len;
uint8_t len_param[2];
int r;
if (plen > BSL_MAX_BLOCK)
plen = BSL_MAX_BLOCK;
len_param[0] = plen & 0xff;
len_param[1] = plen >> 8;
if (send_command(dev->trans, BSL_CMD_TX_BLOCK,
addr, len_param, 2) < 0)
goto fail;
r = recv_packet(dev->trans, mem, plen);
if (r < 0)
goto fail;
if (r < plen) {
printc_err("loadbsl: short response to "
"memory read\n");
return -1;
}
addr += plen;
mem += plen;
len -= plen;
}
return 0;
fail:
printc_err("loadbsl: failed to read block from 0x%04x\n", addr);
return -1;
}
static int loadbsl_writemem(device_t base, address_t addr,
const uint8_t *mem, address_t len)
{
struct loadbsl_device *dev = (struct loadbsl_device *)base;
return do_writemem(dev->trans, addr, mem, len);
}
static int loadbsl_getregs(device_t base, address_t *regs)
{
(void)base;
(void)regs;
printc_err("loadbsl: register fetch is not implemented\n");
return -1;
}
static int loadbsl_setregs(device_t base, const address_t *regs)
{
(void)base;
(void)regs;
printc_err("loadbsl: register store is not implemented\n");
return -1;
}
static int loadbsl_erase(device_t base, device_erase_type_t type,
address_t addr)
{
struct loadbsl_device *dev = (struct loadbsl_device *)base;
switch (type) {
case DEVICE_ERASE_ALL:
printc_err("loadbsl: ERASE_ALL not supported\n");
return -1;
case DEVICE_ERASE_MAIN:
if (send_command(dev->trans, BSL_CMD_MASS_ERASE,
ADDRESS_NONE, NULL, 0) < 0 ||
recv_packet(dev->trans, NULL, 0) < 0) {
printc_err("loadbsl: ERASE_MAIN failed\n");
return -1;
}
break;
case DEVICE_ERASE_SEGMENT:
if (send_command(dev->trans, BSL_CMD_ERASE_SEGMENT,
addr, NULL, 0) < 0 ||
recv_packet(dev->trans, NULL, 0) < 0) {
printc_err("loadbsl: ERASE_SEGMENT failed\n");
return -1;
}
break;
}
return 0;
}
static int loadbsl_ctl(device_t base, device_ctl_t type)
{
(void)base;
switch (type) {
case DEVICE_CTL_HALT:
case DEVICE_CTL_RESET:
return 0;
default:
printc_err("loadbsl: CPU control is not possible\n");
}
return 0;
}
static device_status_t loadbsl_poll(device_t base)
{
(void)base;
return DEVICE_STATUS_HALTED;
}
static device_t loadbsl_open(const struct device_args *args)
{
struct loadbsl_device *dev;
if (args->flags & DEVICE_FLAG_TTY) {
printc_err("loadbsl: this driver does not support "
"tty access\n");
return NULL;
}
dev = malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
dev->base.type = &device_loadbsl;
dev->base.max_breakpoints = 0;
dev->trans = bslhid_open(args->path, args->requested_serial);
if (!dev->trans) {
free(dev);
return NULL;
}
if (rx_password(dev->trans) < 0) {
dev->trans->ops->destroy(dev->trans);
free(dev);
return NULL;
}
if (check_and_load(dev->trans) < 0) {
dev->trans->ops->destroy(dev->trans);
free(dev);
return NULL;
}
return &dev->base;
}
const struct device_class device_loadbsl = {
.name = "load-bsl",
.help = "Loadable USB BSL driver (USB 5xx/6xx).",
.open = loadbsl_open,
.destroy = loadbsl_destroy,
.readmem = loadbsl_readmem,
.writemem = loadbsl_writemem,
.erase = loadbsl_erase,
.getregs = loadbsl_getregs,
.setregs = loadbsl_setregs,
.ctl = loadbsl_ctl,
.poll = loadbsl_poll
};

27
drivers/loadbsl.h Normal file
View File

@ -0,0 +1,27 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2013 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LOADBSL_H_
#define LOADBSL_H_
#include "device.h"
/* MSP430 loadable BSL implementation */
extern const struct device_class device_loadbsl;
#endif

356
drivers/loadbsl_fw.c Normal file
View File

@ -0,0 +1,356 @@
/*
* MSPBLS_RAM_BSL.00.05.04.34
*
* An array holding the bytes to be programmed into device RAM for full USB BSL cabability
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "loadbsl_fw.h"
/* program start addr 0x2504
* first mem addr 0x2500
*/
static const uint8_t RAM_BSL_00_05_04_34[] = {
0x00, 0x05, 0x04, 0x34, 0x31, 0x40, 0x90, 0x33,
0xB0, 0x13, 0x5E, 0x2E, 0x0C, 0x93, 0x00, 0x24,
0xB0, 0x13, 0xF4, 0x2D, 0xFF, 0x3F, 0x12, 0x01,
0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x47, 0x20,
0x00, 0x02, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01,
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85,
0x3F, 0x95, 0x3F, 0x75, 0x08, 0x25, 0x01, 0x15,
0x01, 0x09, 0x01, 0x81, 0x02, 0x85, 0x3F, 0x95,
0x3F, 0x75, 0x08, 0x25, 0x01, 0x15, 0x01, 0x09,
0x01, 0x91, 0x02, 0xC0, 0x09, 0x02, 0x29, 0x00,
0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00,
0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x09, 0x21,
0x01, 0x01, 0x00, 0x01, 0x22, 0x24, 0x00, 0x07,
0x05, 0x81, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05,
0x01, 0x03, 0x40, 0x00, 0x01, 0x57, 0xF2, 0xD2,
0x20, 0x09, 0xF2, 0xD2, 0x22, 0x09, 0x10, 0x01,
0x5E, 0x42, 0x02, 0x24, 0x7E, 0x93, 0x25, 0x24,
0x7E, 0x90, 0x09, 0x00, 0x04, 0x28, 0x7D, 0x42,
0x7E, 0x82, 0x5F, 0x43, 0x0C, 0x3C, 0x7E, 0x92,
0x02, 0x2C, 0x4D, 0x4E, 0x06, 0x3C, 0x7D, 0x42,
0xD2, 0x93, 0x0E, 0x24, 0x02, 0x20, 0x4E, 0x43,
0xF4, 0x3F, 0x7E, 0x43, 0x4F, 0x43, 0xC2, 0x4F,
0x10, 0x24, 0xC2, 0x4E, 0x02, 0x24, 0x4F, 0x43,
0x07, 0x3C, 0x1E, 0x42, 0x06, 0x24, 0xEF, 0x4E,
0x78, 0x23, 0x92, 0x53, 0x06, 0x24, 0x5F, 0x53,
0x4F, 0x9D, 0xF7, 0x2B, 0xC2, 0x4D, 0x21, 0x09,
0x10, 0x01, 0xC2, 0x43, 0x10, 0x24, 0x10, 0x01,
0x82, 0x4C, 0x06, 0x24, 0x5E, 0x42, 0x86, 0x23,
0xC2, 0x9E, 0x02, 0x24, 0x04, 0x28, 0xC2, 0x4E,
0x02, 0x24, 0x4E, 0x43, 0x01, 0x3C, 0x5E, 0x43,
0xC2, 0x4E, 0x0E, 0x24, 0x80, 0x00, 0x80, 0x25,
0xF2, 0xB0, 0x0F, 0x00, 0x84, 0x23, 0x14, 0x20,
0xC2, 0x93, 0x84, 0x23, 0x03, 0x34, 0x5E, 0x42,
0x20, 0x09, 0x02, 0x3C, 0x5E, 0x42, 0x22, 0x09,
0x7E, 0xF2, 0xC2, 0x4E, 0x60, 0x24, 0x5E, 0x42,
0x60, 0x24, 0x42, 0x19, 0x4E, 0x10, 0xC2, 0x4E,
0x60, 0x24, 0xB0, 0x13, 0xC4, 0x27, 0x09, 0x3C,
0xC2, 0x93, 0x84, 0x23, 0x03, 0x34, 0x5E, 0x42,
0xC8, 0x23, 0xEE, 0x3F, 0x5E, 0x42, 0x88, 0x23,
0xEB, 0x3F, 0x3C, 0x40, 0x60, 0x24, 0x80, 0x00,
0xD8, 0x25, 0xF2, 0x43, 0x02, 0x24, 0xC2, 0x43,
0x10, 0x24, 0xC2, 0x43, 0x21, 0x09, 0x10, 0x01,
0xC2, 0x93, 0x82, 0x23, 0x12, 0x20, 0x5E, 0x42,
0x84, 0x23, 0x7E, 0xF0, 0x0F, 0x00, 0x02, 0x20,
0x80, 0x00, 0x42, 0x26, 0x5E, 0x93, 0x0B, 0x20,
0xC2, 0x93, 0x84, 0x23, 0x03, 0x34, 0xF2, 0xD2,
0xC8, 0x23, 0xF6, 0x3F, 0xF2, 0xD2, 0x88, 0x23,
0xF3, 0x3F, 0xB0, 0x13, 0x76, 0x25, 0x10, 0x01,
0xC2, 0x93, 0x80, 0x23, 0x04, 0x34, 0x1F, 0x43,
0xD2, 0xD3, 0x3C, 0x09, 0x03, 0x3C, 0x0F, 0x43,
0xD2, 0xC3, 0x3C, 0x09, 0x5E, 0x42, 0x80, 0x23,
0x7E, 0xB0, 0x60, 0x00, 0x90, 0x20, 0x5D, 0x42,
0x81, 0x23, 0x4D, 0x83, 0x81, 0x24, 0x5D, 0x83,
0x6B, 0x24, 0x6D, 0x83, 0x67, 0x24, 0x6D, 0x83,
0x45, 0x24, 0x5D, 0x83, 0x09, 0x24, 0x6D, 0x83,
0x52, 0x24, 0x5D, 0x83, 0x46, 0x24, 0x5D, 0x83,
0x33, 0x24, 0x5D, 0x83, 0x54, 0x24, 0x7B, 0x3C,
0x0F, 0x93, 0x79, 0x24, 0x5E, 0x42, 0x83, 0x23,
0x5E, 0x83, 0x08, 0x24, 0x5E, 0x83, 0x0F, 0x24,
0x7E, 0x80, 0x1F, 0x00, 0x1C, 0x24, 0x5E, 0x83,
0x13, 0x24, 0x6D, 0x3C, 0xC2, 0x43, 0x23, 0x09,
0xF2, 0x40, 0x12, 0x00, 0x02, 0x24, 0x3C, 0x40,
0x16, 0x25, 0x80, 0x00, 0xD8, 0x25, 0xC2, 0x43,
0x23, 0x09, 0xF2, 0x40, 0x29, 0x00, 0x02, 0x24,
0x3C, 0x40, 0x4C, 0x25, 0x80, 0x00, 0xD8, 0x25,
0xF2, 0x40, 0x24, 0x00, 0x02, 0x24, 0x3C, 0x40,
0x28, 0x25, 0x80, 0x00, 0xD8, 0x25, 0xC2, 0x43,
0x23, 0x09, 0xF2, 0x40, 0x09, 0x00, 0x02, 0x24,
0x3C, 0x40, 0x5E, 0x25, 0x80, 0x00, 0xD8, 0x25,
0x0F, 0x93, 0x49, 0x24, 0xB0, 0x13, 0xC4, 0x27,
0xC2, 0x43, 0x60, 0x24, 0xD2, 0x42, 0x01, 0x24,
0x61, 0x24, 0x3B, 0x3C, 0xB0, 0x13, 0xCE, 0x27,
0xD2, 0x42, 0x82, 0x23, 0x3F, 0x09, 0x80, 0x00,
0x42, 0x26, 0xB0, 0x13, 0xCE, 0x27, 0xD2, 0x42,
0x82, 0x23, 0x00, 0x24, 0xB0, 0x13, 0x42, 0x26,
0xD2, 0x43, 0x12, 0x24, 0x10, 0x01, 0xC2, 0x43,
0x23, 0x09, 0xD2, 0x43, 0x02, 0x24, 0x3C, 0x40,
0x00, 0x24, 0x80, 0x00, 0xD8, 0x25, 0xB0, 0x13,
0xCE, 0x27, 0xD2, 0x42, 0x84, 0x23, 0x01, 0x24,
0x80, 0x00, 0x42, 0x26, 0x80, 0x00, 0x50, 0x26,
0x5E, 0x42, 0x84, 0x23, 0x7E, 0xF0, 0x0F, 0x00,
0x02, 0x20, 0x80, 0x00, 0x42, 0x26, 0x5E, 0x93,
0x18, 0x20, 0xC2, 0x93, 0x84, 0x23, 0x04, 0x34,
0xF2, 0xF0, 0xD7, 0x00, 0xC8, 0x23, 0xF5, 0x3F,
0xF2, 0xF0, 0xD7, 0x00, 0x88, 0x23, 0xF1, 0x3F,
0x7E, 0x90, 0x80, 0x00, 0x03, 0x20, 0xB0, 0x13,
0xC4, 0x27, 0x43, 0x3F, 0x7E, 0x90, 0x82, 0x00,
0x02, 0x20, 0x80, 0x00, 0xF8, 0x25, 0xB0, 0x13,
0x76, 0x25, 0x10, 0x01, 0xC2, 0x43, 0x23, 0x09,
0xE2, 0x43, 0x02, 0x24, 0x10, 0x01, 0xD5, 0x3E,
0x1B, 0x15, 0x1F, 0x42, 0x5A, 0x24, 0x5B, 0x4F,
0x03, 0x00, 0x5E, 0x4F, 0x01, 0x00, 0x5C, 0x4F,
0x02, 0x00, 0x8C, 0x10, 0x0C, 0xDE, 0x0D, 0x4B,
0x0E, 0x4F, 0x2E, 0x52, 0x6A, 0x4F, 0x7A, 0x80,
0x10, 0x00, 0x29, 0x24, 0x5A, 0x83, 0x14, 0x24,
0x5A, 0x83, 0x2A, 0x24, 0x5A, 0x83, 0x2E, 0x24,
0x6A, 0x83, 0x23, 0x24, 0x5A, 0x83, 0x3A, 0x24,
0x5A, 0x83, 0x15, 0x24, 0x5A, 0x83, 0x3B, 0x24,
0x5A, 0x83, 0x3E, 0x24, 0x6A, 0x83, 0x41, 0x20,
0x5F, 0x43, 0xB0, 0x13, 0xE2, 0x2B, 0x41, 0x3C,
0x1F, 0x53, 0x0C, 0x4F, 0xB0, 0x13, 0x38, 0x2C,
0x4C, 0x93, 0x02, 0x20, 0x4C, 0x43, 0x37, 0x3C,
0x7C, 0x40, 0x05, 0x00, 0x34, 0x3C, 0xB0, 0x13,
0x66, 0x2E, 0x03, 0x20, 0xB0, 0x13, 0x6E, 0x2E,
0xF5, 0x3F, 0x6C, 0x42, 0x2C, 0x3C, 0x4F, 0x43,
0xE8, 0x3F, 0xB0, 0x13, 0xD4, 0x2D, 0x27, 0x3C,
0x0E, 0x4C, 0x0F, 0x4B, 0x4C, 0x43, 0xB0, 0x13,
0xD4, 0x2C, 0x21, 0x3C, 0xB0, 0x13, 0x66, 0x2E,
0xF0, 0x23, 0x4C, 0x43, 0x1F, 0x42, 0x58, 0x24,
0x3F, 0x50, 0x40, 0x00, 0x1B, 0x42, 0x44, 0x01,
0x3B, 0xF0, 0x10, 0x00, 0x0F, 0x5B, 0x82, 0x4F,
0x44, 0x01, 0x11, 0x3C, 0xB0, 0x13, 0x3C, 0x2E,
0xB0, 0x13, 0x12, 0x2B, 0x0E, 0x3C, 0xB0, 0x13,
0x3C, 0x2E, 0xB0, 0x13, 0x66, 0x29, 0x09, 0x3C,
0x2E, 0x42, 0x3C, 0x40, 0x00, 0x25, 0x0D, 0x43,
0xF8, 0x3F, 0x7C, 0x40, 0x07, 0x00, 0xB0, 0x13,
0x12, 0x2E, 0x1A, 0x17, 0x10, 0x01, 0xE2, 0xB2,
0x3E, 0x09, 0x14, 0x28, 0xF2, 0x40, 0x80, 0x00,
0x23, 0x09, 0x03, 0x3C, 0xF2, 0xF0, 0xFA, 0x00,
0x3E, 0x09, 0xC2, 0x43, 0x10, 0x24, 0xC2, 0x43,
0x60, 0x24, 0xC2, 0x43, 0x61, 0x24, 0xB0, 0x13,
0x80, 0x26, 0xD2, 0xB3, 0x3E, 0x09, 0xF2, 0x2F,
0xE2, 0xC2, 0x3E, 0x09, 0x1F, 0x42, 0x32, 0x09,
0x7F, 0x90, 0x0A, 0x00, 0x0C, 0x20, 0xB0, 0x13,
0x4A, 0x2E, 0xB0, 0x13, 0x86, 0x2C, 0xB0, 0x13,
0x08, 0x2A, 0xB2, 0xF0, 0xF9, 0xFF, 0x08, 0x09,
0xA2, 0xD3, 0x02, 0x09, 0x10, 0x01, 0x7F, 0x90,
0x0C, 0x00, 0x06, 0x20, 0xB0, 0x13, 0x4A, 0x2E,
0xB2, 0x40, 0x04, 0xA5, 0x20, 0x01, 0x10, 0x01,
0x7F, 0x90, 0x12, 0x00, 0x0A, 0x20, 0xC2, 0x43,
0x23, 0x09, 0xD2, 0x93, 0x10, 0x24, 0x02, 0x20,
0x80, 0x00, 0x80, 0x25, 0xF2, 0xD2, 0x20, 0x09,
0x10, 0x01, 0x7F, 0x90, 0x16, 0x00, 0x02, 0x20,
0x80, 0x00, 0x08, 0x2A, 0x7F, 0x90, 0x18, 0x00,
0x0C, 0x20, 0xD2, 0x43, 0x11, 0x24, 0xF2, 0xC0,
0x40, 0x00, 0x3E, 0x09, 0xB2, 0x40, 0x80, 0x00,
0x10, 0x09, 0xF2, 0x40, 0x20, 0x00, 0x3D, 0x09,
0x10, 0x01, 0x7F, 0x90, 0x1A, 0x00, 0x0A, 0x20,
0xB0, 0x13, 0x86, 0x2C, 0xF2, 0xF0, 0x9F, 0x00,
0x3E, 0x09, 0xF2, 0x40, 0xC0, 0x00, 0x3D, 0x09,
0xC2, 0x43, 0x11, 0x24, 0x10, 0x01, 0x7B, 0x15,
0x0A, 0x4C, 0x0B, 0x4D, 0x0F, 0x4E, 0x3F, 0xE3,
0x0F, 0x5F, 0x0F, 0x7F, 0x08, 0x4C, 0x09, 0x4D,
0x08, 0x5E, 0x09, 0x6F, 0x47, 0x43, 0x0B, 0x3C,
0x1F, 0x42, 0x5C, 0x24, 0xFF, 0x40, 0x3A, 0x00,
0x00, 0x00, 0x0C, 0x46, 0x1C, 0x53, 0xB0, 0x13,
0x2A, 0x2E, 0x0A, 0x56, 0x0B, 0x63, 0x0B, 0x99,
0x03, 0x28, 0x34, 0x20, 0x0A, 0x98, 0x32, 0x2C,
0x47, 0x93, 0x30, 0x20, 0x0E, 0x48, 0x0F, 0x49,
0x0E, 0x8A, 0x0F, 0x7B, 0x03, 0x20, 0x3E, 0x90,
0x3E, 0x00, 0x03, 0x28, 0x36, 0x40, 0x3D, 0x00,
0x02, 0x3C, 0x06, 0x48, 0x06, 0x8A, 0x14, 0x42,
0x5C, 0x24, 0x14, 0x53, 0x0E, 0x46, 0x0F, 0x46,
0x3F, 0xE3, 0x0F, 0x5F, 0x0F, 0x7F, 0x0E, 0x5A,
0x0F, 0x6B, 0x09, 0x3C, 0x1F, 0x15, 0x0D, 0x16,
0x6C, 0x4D, 0x0D, 0x4E, 0x0D, 0x8A, 0x05, 0x44,
0x05, 0x5D, 0xC5, 0x4C, 0x00, 0x00, 0x3E, 0x53,
0x3F, 0x63, 0x0F, 0x9B, 0xC9, 0x2B, 0x02, 0x20,
0x0E, 0x9A, 0xC6, 0x2B, 0xB0, 0x13, 0x66, 0x2E,
0xED, 0x27, 0x67, 0x42, 0x6C, 0x42, 0xB0, 0x13,
0x12, 0x2E, 0xC7, 0x3F, 0x74, 0x17, 0x10, 0x01,
0xF2, 0x40, 0x10, 0x00, 0x3C, 0x09, 0xC2, 0x43,
0x12, 0x24, 0xC2, 0x43, 0x11, 0x24, 0xC2, 0x43,
0x00, 0x24, 0xC2, 0x43, 0x01, 0x24, 0xC2, 0x43,
0x3C, 0x09, 0xF2, 0x43, 0x02, 0x24, 0xF2, 0x43,
0x04, 0x24, 0xC2, 0x43, 0x10, 0x24, 0x7E, 0x40,
0x80, 0x00, 0xC2, 0x4E, 0x21, 0x09, 0xC2, 0x4E,
0x23, 0x09, 0xF2, 0x40, 0x8C, 0x00, 0x20, 0x09,
0xF2, 0x40, 0x8C, 0x00, 0x22, 0x09, 0xF2, 0x40,
0x03, 0x00, 0x2F, 0x09, 0xF2, 0x40, 0x03, 0x00,
0x2E, 0x09, 0xC2, 0x4E, 0xC8, 0x23, 0xF2, 0x40,
0x10, 0x00, 0xC9, 0x23, 0xC2, 0x4E, 0xCA, 0x23,
0xC2, 0x4E, 0xCE, 0x23, 0xF2, 0x40, 0x40, 0x00,
0xCF, 0x23, 0xC2, 0x4E, 0x88, 0x23, 0xC2, 0x43,
0x89, 0x23, 0xC2, 0x43, 0x8A, 0x23, 0xF2, 0x40,
0x40, 0x00, 0x8F, 0x23, 0xF2, 0x40, 0x40, 0x00,
0x3C, 0x09, 0xC2, 0x43, 0x3E, 0x09, 0xF2, 0x40,
0xC0, 0x00, 0x3D, 0x09, 0x10, 0x01, 0x7B, 0x15,
0x08, 0x4C, 0x07, 0x4D, 0x04, 0x4F, 0x4C, 0x43,
0x0A, 0x48, 0x0B, 0x4D, 0x0F, 0x4E, 0x3F, 0xE3,
0x0F, 0x5F, 0x0F, 0x7F, 0x06, 0x48, 0x06, 0x5E,
0x07, 0x6F, 0x02, 0x3C, 0x1A, 0x53, 0x0B, 0x63,
0x0B, 0x97, 0x03, 0x28, 0x2C, 0x20, 0x0A, 0x96,
0x2A, 0x2C, 0x18, 0xB3, 0x08, 0x2C, 0x0E, 0x46,
0x0F, 0x47, 0x3E, 0x53, 0x3F, 0x63, 0x0A, 0x9E,
0x19, 0x20, 0x0B, 0x9F, 0x17, 0x20, 0x6E, 0x44,
0xB0, 0x13, 0x66, 0x2E, 0x10, 0x20, 0x4C, 0x43,
0xB0, 0x13, 0x56, 0x2E, 0x1B, 0x15, 0x0F, 0x16,
0xCF, 0x4E, 0x00, 0x00, 0xB0, 0x13, 0x56, 0x2E,
0x1B, 0x15, 0x0F, 0x16, 0x6D, 0x4F, 0x4E, 0x9D,
0x03, 0x24, 0x5C, 0x43, 0x01, 0x3C, 0x6C, 0x42,
0x14, 0x53, 0x07, 0x3C, 0x3E, 0x44, 0x0C, 0x4A,
0x0D, 0x4B, 0xB0, 0x13, 0x64, 0x2D, 0x1A, 0x53,
0x0B, 0x63, 0x4C, 0x93, 0xCF, 0x27, 0x74, 0x17,
0x10, 0x01, 0x3B, 0x15, 0x0A, 0x4E, 0xB2, 0x43,
0x54, 0x01, 0x08, 0x4C, 0x09, 0x4D, 0x07, 0x3C,
0x19, 0x15, 0x0E, 0x16, 0x6F, 0x4E, 0xC2, 0x4F,
0x52, 0x01, 0x18, 0x53, 0x09, 0x63, 0x0E, 0x4C,
0x0F, 0x4D, 0x0E, 0x5A, 0x0F, 0x63, 0x09, 0x9F,
0x03, 0x28, 0x09, 0x20, 0x08, 0x9E, 0x07, 0x2C,
0xB0, 0x13, 0x66, 0x2E, 0xED, 0x27, 0x6C, 0x42,
0xB0, 0x13, 0x12, 0x2E, 0x15, 0x3C, 0x1E, 0x42,
0x54, 0x01, 0x1F, 0x42, 0x5C, 0x24, 0xFF, 0x40,
0x3A, 0x00, 0x00, 0x00, 0x1B, 0x42, 0x5C, 0x24,
0xCB, 0x4E, 0x01, 0x00, 0x47, 0x18, 0x0E, 0x11,
0x1F, 0x42, 0x5C, 0x24, 0xCF, 0x4E, 0x02, 0x00,
0x3C, 0x40, 0x03, 0x00, 0xB0, 0x13, 0x2A, 0x2E,
0x38, 0x17, 0x10, 0x01, 0x32, 0xC2, 0x03, 0x43,
0xB2, 0x40, 0x02, 0x1C, 0x5A, 0x24, 0xB2, 0x40,
0x17, 0x24, 0x5C, 0x24, 0xB2, 0x40, 0x28, 0x96,
0x00, 0x09, 0x82, 0x43, 0x02, 0x09, 0x82, 0x43,
0x60, 0x01, 0xB2, 0x40, 0xF3, 0x10, 0x64, 0x01,
0xB2, 0x40, 0x40, 0x00, 0x62, 0x01, 0xB2, 0x40,
0x44, 0x02, 0x68, 0x01, 0xC2, 0x43, 0x0E, 0x24,
0xC2, 0x43, 0x11, 0x24, 0xB2, 0x40, 0x28, 0x96,
0x00, 0x09, 0xB2, 0x40, 0x40, 0x1E, 0x08, 0x09,
0xB2, 0x40, 0x80, 0x00, 0x04, 0x09, 0xB0, 0x13,
0x4A, 0x2E, 0xC2, 0x43, 0x12, 0x24, 0xB2, 0xB2,
0x08, 0x09, 0x06, 0x28, 0xB0, 0x13, 0x86, 0x2C,
0xB0, 0x13, 0x08, 0x2A, 0xA2, 0xD3, 0x02, 0x09,
0x10, 0x01, 0x3B, 0x15, 0x4A, 0x4F, 0x6F, 0x42,
0x3B, 0x40, 0x58, 0x24, 0xB0, 0x13, 0x66, 0x2E,
0x08, 0x20, 0x4F, 0x43, 0xA2, 0x4B, 0x44, 0x01,
0x28, 0x4B, 0x38, 0x50, 0x40, 0x00, 0x82, 0x48,
0x40, 0x01, 0x4F, 0x93, 0x0B, 0x20, 0xB2, 0x90,
0x05, 0x00, 0x5E, 0x24, 0x07, 0x38, 0x0F, 0x4E,
0x1E, 0x42, 0x5E, 0x24, 0x2E, 0x82, 0xB0, 0x13,
0x8E, 0x2A, 0x4F, 0x4C, 0x4A, 0x93, 0x03, 0x20,
0x4C, 0x4F, 0xB0, 0x13, 0x12, 0x2E, 0xA2, 0x4B,
0x40, 0x01, 0x2F, 0x4B, 0x3F, 0x50, 0x10, 0x00,
0x82, 0x4F, 0x44, 0x01, 0x38, 0x17, 0x10, 0x01,
0x1B, 0x15, 0x21, 0x83, 0x0D, 0x43, 0x3A, 0x40,
0xE0, 0xFF, 0x0B, 0x43, 0x7E, 0x4A, 0x0F, 0x4C,
0x0F, 0x5B, 0x6F, 0x4F, 0x0E, 0xEF, 0x0D, 0xDE,
0x1B, 0x53, 0x3B, 0x90, 0x20, 0x00, 0xF6, 0x2B,
0x0D, 0x93, 0x0E, 0x20, 0xB1, 0x40, 0xFF, 0x7F,
0x00, 0x00, 0x02, 0x3C, 0xB1, 0x53, 0x00, 0x00,
0x91, 0x93, 0x00, 0x00, 0xFB, 0x37, 0xB2, 0x40,
0xA5, 0xA5, 0x56, 0x24, 0x4C, 0x43, 0x04, 0x3C,
0xB0, 0x13, 0xD4, 0x2D, 0x7C, 0x40, 0x05, 0x00,
0x21, 0x53, 0x1A, 0x17, 0x10, 0x01, 0x21, 0x82,
0x81, 0x43, 0x02, 0x00, 0xB2, 0x40, 0x28, 0x96,
0x00, 0x09, 0x92, 0xD3, 0x02, 0x09, 0x92, 0x42,
0x14, 0x24, 0x12, 0x09, 0xB2, 0x40, 0x00, 0x13,
0x10, 0x09, 0x82, 0x43, 0x14, 0x09, 0x81, 0x43,
0x00, 0x00, 0x02, 0x3C, 0x91, 0x53, 0x00, 0x00,
0xB1, 0x90, 0x64, 0x00, 0x00, 0x00, 0xFA, 0x2B,
0x1F, 0x41, 0x02, 0x00, 0x0E, 0x4F, 0x1E, 0x53,
0x81, 0x4E, 0x02, 0x00, 0x3F, 0x90, 0xE9, 0x03,
0x03, 0x2C, 0x82, 0x93, 0x14, 0x09, 0xE9, 0x23,
0x21, 0x52, 0x10, 0x01, 0xB0, 0x13, 0x66, 0x2E,
0x0E, 0x20, 0x4C, 0x43, 0xB0, 0x13, 0xFA, 0x2C,
0x1D, 0x42, 0x58, 0x24, 0x2D, 0x53, 0x82, 0x4D,
0x40, 0x01, 0x1F, 0x15, 0x0D, 0x16, 0xCD, 0x43,
0x00, 0x00, 0x80, 0x00, 0x08, 0x2D, 0x6C, 0x42,
0x10, 0x01, 0x92, 0xB3, 0x44, 0x01, 0xFD, 0x2F,
0x92, 0x42, 0x58, 0x24, 0x44, 0x01, 0x10, 0x01,
0x92, 0xB3, 0x44, 0x01, 0xFD, 0x2F, 0x1F, 0x42,
0x58, 0x24, 0x3F, 0x50, 0x10, 0x00, 0x82, 0x4F,
0x44, 0x01, 0x10, 0x01, 0x82, 0x43, 0x5E, 0x24,
0xC2, 0x43, 0x8A, 0x23, 0xB0, 0x13, 0xA6, 0x28,
0xD2, 0x93, 0x12, 0x24, 0x0D, 0x20, 0xC2, 0x93,
0x11, 0x24, 0x0A, 0x20, 0x4F, 0x43, 0xC2, 0x93,
0x8A, 0x23, 0x04, 0x34, 0x5F, 0x42, 0x8A, 0x23,
0x7F, 0xF0, 0x7F, 0x00, 0x82, 0x4F, 0x5E, 0x24,
0x82, 0x93, 0x5E, 0x24, 0xEB, 0x27, 0x92, 0x93,
0x5E, 0x24, 0x06, 0x38, 0x5F, 0x42, 0x01, 0x1C,
0x82, 0x4F, 0x5E, 0x24, 0x5C, 0x43, 0x10, 0x01,
0x4C, 0x43, 0x10, 0x01, 0x1B, 0x15, 0xB0, 0x13,
0x66, 0x2E, 0x15, 0x20, 0x4F, 0x43, 0xB0, 0x13,
0x56, 0x2E, 0x1D, 0x15, 0x0A, 0x16, 0x8A, 0x4E,
0x00, 0x00, 0xB0, 0x13, 0x56, 0x2E, 0x1D, 0x15,
0x0A, 0x16, 0x2B, 0x4A, 0x0E, 0x9B, 0x01, 0x24,
0x5F, 0x43, 0x92, 0xB3, 0x46, 0x01, 0x04, 0x28,
0x7F, 0x40, 0x03, 0x00, 0x01, 0x3C, 0x6F, 0x42,
0x4C, 0x4F, 0x1A, 0x17, 0x10, 0x01, 0x0A, 0x12,
0x7E, 0x40, 0x3F, 0x00, 0xC2, 0x93, 0xCA, 0x23,
0x11, 0x34, 0xC2, 0x4E, 0x80, 0x1C, 0x3D, 0x40,
0x81, 0x1C, 0x4F, 0x43, 0x0A, 0x4C, 0x0A, 0x5F,
0xED, 0x4A, 0x00, 0x00, 0x1D, 0x53, 0x5F, 0x53,
0x4F, 0x9E, 0xF8, 0x2B, 0xF2, 0x40, 0x40, 0x00,
0xCA, 0x23, 0x01, 0x3C, 0x4E, 0x43, 0x4C, 0x4E,
0x3A, 0x41, 0x10, 0x01, 0xB0, 0x13, 0xFA, 0x2C,
0xB0, 0x13, 0x56, 0x2E, 0x1F, 0x42, 0x58, 0x24,
0x3F, 0x50, 0x06, 0x00, 0x82, 0x4F, 0x40, 0x01,
0xC2, 0x43, 0xE0, 0xFF, 0xB0, 0x13, 0x08, 0x2D,
0x4C, 0x43, 0x10, 0x01, 0xB2, 0x40, 0xA5, 0xA5,
0x56, 0x24, 0xB2, 0x40, 0x00, 0xA5, 0x58, 0x24,
0xB0, 0x13, 0x7C, 0x2B, 0xB0, 0x13, 0x1C, 0x2D,
0x5C, 0xB3, 0xFC, 0x2B, 0xB0, 0x13, 0xD0, 0x27,
0xF9, 0x3F, 0x1F, 0x42, 0x5C, 0x24, 0xFF, 0x40,
0x3B, 0x00, 0x00, 0x00, 0x1F, 0x42, 0x5C, 0x24,
0xCF, 0x4C, 0x01, 0x00, 0x2C, 0x43, 0x80, 0x00,
0x2A, 0x2E, 0xC2, 0x4C, 0x16, 0x24, 0x3C, 0x40,
0x16, 0x24, 0xB0, 0x13, 0x9E, 0x2D, 0x4C, 0x93,
0xFA, 0x27, 0x10, 0x01, 0x6E, 0x4E, 0x5F, 0x4F,
0x05, 0x00, 0x47, 0x18, 0x0F, 0x5F, 0x0E, 0xDF,
0x10, 0x01, 0x03, 0x43, 0x3F, 0x40, 0xDE, 0x2E,
0x3F, 0x53, 0xFE, 0x2F, 0x10, 0x01, 0x92, 0xB3,
0x44, 0x01, 0xFD, 0x2F, 0x10, 0x01, 0xB2, 0x40,
0x80, 0x5A, 0x5C, 0x01, 0x10, 0x01, 0xB2, 0x90,
0xA5, 0xA5, 0x56, 0x24, 0x10, 0x01, 0x1D, 0x15,
0x10, 0x01
};
const struct loadbsl_fw loadbsl_fw_usb5xx = {
.data = RAM_BSL_00_05_04_34,
.size = sizeof(RAM_BSL_00_05_04_34),
.prog_addr = 0x2500,
.entry_point = 0x2504
};

34
drivers/loadbsl_fw.h Normal file
View File

@ -0,0 +1,34 @@
/* MSPDebug - debugging tool for the eZ430
* Copyright (C) 2009-2012 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LOADBSL_FW_H_
#define LOADBSL_FW_H_
#include <stdint.h>
/* USB BSL firmware image */
struct loadbsl_fw {
const uint8_t *data;
const uint32_t size;
const uint32_t prog_addr;
const uint32_t entry_point;
};
extern const struct loadbsl_fw loadbsl_fw_usb5xx;
#endif

378
transport/bslhid.c Normal file
View File

@ -0,0 +1,378 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2013 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <usb.h>
#include <string.h>
#include "usbutil.h"
#include "output.h"
#include "output_util.h"
#include "bslhid.h"
#define BSLHID_VID 0x2047
#define BSLHID_PID 0x0200
#define BSLHID_CLASS USB_CLASS_HID
#define BSLHID_XFER_SIZE 64
#define BSLHID_MTU (BSLHID_XFER_SIZE - 2)
#define BSLHID_HEADER 0x3F
#define BSLHID_TIMEOUT 5000
struct bslhid_transport {
struct transport base;
int cfg_number;
int int_number;
struct usb_dev_handle *handle;
int in_ep;
int out_ep;
char bus_name[PATH_MAX + 1];
};
static int find_interface(struct bslhid_transport *tr,
const struct usb_device *dev)
{
int c;
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
const struct usb_config_descriptor *cfg = &dev->config[c];
int i;
for (i = 0; i < cfg->bNumInterfaces; i++) {
const struct usb_interface *intf = &cfg->interface[i];
const struct usb_interface_descriptor *desc =
&intf->altsetting[0];
if (desc->bInterfaceClass == BSLHID_CLASS) {
tr->cfg_number = c;
tr->int_number = i;
return 0;
}
}
}
printc_err("bslhid: can't find a matching interface\n");
return -1;
}
static int find_endpoints(struct bslhid_transport *tr,
const struct usb_device *dev)
{
const struct usb_interface_descriptor *desc =
&dev->config[tr->cfg_number].interface[tr->int_number].
altsetting[0];
int i;
tr->in_ep = -1;
tr->out_ep = -1;
for (i = 0; i < desc->bNumEndpoints; i++) {
int addr = desc->endpoint[i].bEndpointAddress;
if (addr & USB_ENDPOINT_DIR_MASK)
tr->in_ep = addr;
else
tr->out_ep = addr;
}
if (tr->in_ep < 0 || tr->out_ep < 0) {
printc_err("bslhid: can't find suitable endpoints\n");
return -1;
}
return 0;
}
static int open_device(struct bslhid_transport *tr, struct usb_device *dev)
{
if (find_interface(tr, dev) < 0)
return -1;
printc_dbg("Opening interface %d (config %d)...\n",
tr->int_number, tr->cfg_number);
if (find_endpoints(tr, dev) < 0)
return -1;
printc_dbg("Found endpoints: IN: 0x%02x, OUT: 0x%02x\n",
tr->in_ep, tr->out_ep);
tr->handle = usb_open(dev);
if (!tr->handle) {
pr_error("bslhid: can't open device");
return -1;
}
#ifdef __Windows__
if (usb_set_configuration(tr->handle, tr->cfg_number) < 0)
pr_error("warning: bslhid: can't set configuration");
#endif
#ifdef __linux__
if (usb_detach_kernel_driver_np(tr->handle, tr->int_number) < 0)
pr_error("warning: bslhid: can't detach kernel driver");
#endif
if (usb_claim_interface(tr->handle, tr->int_number) < 0) {
pr_error("bslhid: can't claim interface");
usb_close(tr->handle);
return -1;
}
/* Save the bus path for a future suspend/resume */
strncpy(tr->bus_name, dev->bus->dirname, sizeof(tr->bus_name));
tr->bus_name[sizeof(tr->bus_name) - 1] = 0;
return 0;
}
static void bslhid_destroy(transport_t base)
{
struct bslhid_transport *tr = (struct bslhid_transport *)base;
if (tr->handle) {
usb_release_interface(tr->handle, tr->int_number);
usb_close(tr->handle);
}
free(tr);
}
static int bslhid_flush(transport_t base)
{
#ifndef __APPLE__
struct bslhid_transport *tr = (struct bslhid_transport *)base;
uint8_t inbuf[BSLHID_XFER_SIZE];
if (!tr->handle)
return 0;
while (usb_bulk_read(tr->handle, tr->in_ep,
(char *)inbuf, sizeof(inbuf), 100) > 0);
#endif
return 0;
}
static int bslhid_send(transport_t base, const uint8_t *data, int len)
{
struct bslhid_transport *tr = (struct bslhid_transport *)base;
uint8_t outbuf[BSLHID_XFER_SIZE];
if (!tr->handle) {
printc_err("bslhid: send on suspended device\n");
return -1;
}
memset(outbuf, 0xac, sizeof(outbuf));
if (len > BSLHID_MTU) {
printc_err("bslhid: send in excess of MTU: %d\n", len);
return -1;
}
outbuf[0] = BSLHID_HEADER;
outbuf[1] = len;
memcpy(outbuf + 2, data, len);
#ifdef DEBUG_BSLHID
debug_hexdump("bslhid_send", outbuf, sizeof(outbuf));
#endif
if (usb_bulk_write(tr->handle, tr->out_ep,
(char *)outbuf, sizeof(outbuf),
BSLHID_TIMEOUT) < 0) {
printc_err("bslhid: usb_bulk_write: %s\n", usb_strerror());
return -1;
}
return 0;
}
static int bslhid_recv(transport_t base, uint8_t *data, int max_len)
{
struct bslhid_transport *tr = (struct bslhid_transport *)base;
uint8_t inbuf[BSLHID_XFER_SIZE];
int r;
int len;
if (!tr->handle) {
printc_err("bslhid: recv on suspended device\n");
return -1;
}
r = usb_bulk_read(tr->handle, tr->in_ep,
(char *)inbuf, sizeof(inbuf), BSLHID_TIMEOUT);
if (r <= 0) {
printc_err("bslhid_recv: usb_bulk_read: %s\n", usb_strerror());
return -1;
}
#ifdef DEBUG_BSLHID
debug_hexdump("bslhid_recv", inbuf, r);
#endif
if (r < 2) {
printc_err("bslhid_recv: short transfer\n");
return -1;
}
if (inbuf[0] != BSLHID_HEADER) {
printc_err("bslhid_recv: missing transfer header\n");
return -1;
}
len = inbuf[1];
if ((len > max_len) || (len + 2 > r)) {
printc_err("bslhid_recv: bad length: %d (%d byte transfer)\n",
len, r);
return -1;
}
memcpy(data, inbuf + 2, len);
return len;
}
static int bslhid_set_modem(transport_t base, transport_modem_t state)
{
printc_err("bslhid: unsupported operation: set_modem\n");
return -1;
}
static int bslhid_suspend(transport_t base)
{
struct bslhid_transport *tr = (struct bslhid_transport *)base;
if (tr->handle) {
usb_release_interface(tr->handle, tr->int_number);
usb_close(tr->handle);
tr->handle = NULL;
}
return 0;
}
static struct usb_bus *find_by_name(const char *name)
{
struct usb_bus *b;
for (b = usb_get_busses(); b; b = b->next)
if (!strcmp(name, b->dirname))
return b;
return NULL;
}
static struct usb_device *find_first_bsl(struct usb_bus *bus)
{
struct usb_device *d;
for (d = bus->devices; d; d = d->next)
if ((d->descriptor.idVendor == BSLHID_VID) &&
(d->descriptor.idProduct == BSLHID_PID))
return d;
return NULL;
}
static int bslhid_resume(transport_t base)
{
struct bslhid_transport *tr = (struct bslhid_transport *)base;
struct usb_bus *bus;
struct usb_device *dev;
if (tr->handle)
return 0;
usb_init();
usb_find_busses();
usb_find_devices();
bus = find_by_name(tr->bus_name);
if (!bus) {
printc_err("bslhid: can't find bus to resume from\n");
return -1;
}
/* We can't portably distinguish physical locations, so this
* will have to do.
*/
dev = find_first_bsl(bus);
if (!dev) {
printc_err("bslhid: can't find a BSL HID on this bus\n");
return -1;
}
if (open_device(tr, dev) < 0) {
printc_err("bslhid: failed to resume BSL HID device\n");
return -1;
}
return 0;
}
static const struct transport_class bslhid_transport_class = {
.destroy = bslhid_destroy,
.send = bslhid_send,
.recv = bslhid_recv,
.flush = bslhid_flush,
.set_modem = bslhid_set_modem,
.suspend = bslhid_suspend,
.resume = bslhid_resume
};
transport_t bslhid_open(const char *dev_path, const char *requested_serial)
{
struct bslhid_transport *tr = malloc(sizeof(*tr));
struct usb_device *dev;
if (!tr) {
pr_error("bslhid: can't allocate memory");
return NULL;
}
memset(tr, 0, sizeof(*tr));
tr->base.ops = &bslhid_transport_class;
usb_init();
usb_find_busses();
usb_find_devices();
if (dev_path)
dev = usbutil_find_by_loc(dev_path);
else
dev = usbutil_find_by_id(BSLHID_VID, BSLHID_PID,
requested_serial);
if (!dev) {
free(tr);
return NULL;
}
if (open_device(tr, dev) < 0) {
printc_err("bslhid: failed to open BSL HID device\n");
free(tr);
return NULL;
}
bslhid_flush(&tr->base);
return &tr->base;
}

30
transport/bslhid.h Normal file
View File

@ -0,0 +1,30 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009-2013 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BSLHID_H_
#define BSLHID_H_
#include "transport.h"
/* Open a USB HID device used to wrap the USB bootstrap loader serial
* protocol. The interface is described in SLAU319C: "MSP430 Programming
* via the Bootstrap Loader".
*/
transport_t bslhid_open(const char *dev_path, const char *requested_serial);
#endif

View File

@ -54,6 +54,7 @@
#include "input.h" #include "input.h"
#include "input_async.h" #include "input_async.h"
#include "pif.h" #include "pif.h"
#include "loadbsl.h"
#ifdef __CYGWIN__ #ifdef __CYGWIN__
#include <sys/cygwin.h> #include <sys/cygwin.h>
@ -82,7 +83,8 @@ static const struct device_class *const driver_table[] = {
&device_gdbc, &device_gdbc,
&device_tilib, &device_tilib,
&device_goodfet, &device_goodfet,
&device_pif &device_pif,
&device_loadbsl
}; };
static const char *version_text = static const char *version_text =

View File

@ -1,5 +1,5 @@
/* MSPDebug - debugging tool for MSP430 MCUs /* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 Daniel Beer * Copyright (C) 2009-2013 Daniel Beer
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -36,7 +36,8 @@ static const char *device_help(const struct usb_device *dev)
{0x15ba, 0x0002, "Olimex MSP430-JTAG-TINY (v1)"}, {0x15ba, 0x0002, "Olimex MSP430-JTAG-TINY (v1)"},
{0x15ba, 0x0008, "Olimex MSP430-JTAG-ISO"}, {0x15ba, 0x0008, "Olimex MSP430-JTAG-ISO"},
{0x15ba, 0x0031, "Olimex MSP430-JTAG-TINY (v2)"}, {0x15ba, 0x0031, "Olimex MSP430-JTAG-TINY (v2)"},
{0x15ba, 0x0100, "Olimex MSP430-JTAG-ISO-MK2 (v2)"} {0x15ba, 0x0100, "Olimex MSP430-JTAG-ISO-MK2 (v2)"},
{0x2047, 0x0200, "USB bootstrap loader"}
}; };
int i; int i;