Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

CROSS ?=
USB ?= libusb

AS := $(CROSS)gcc -x assembler-with-cpp
CC := $(CROSS)gcc
Expand All @@ -23,10 +24,15 @@ ODFLAGS :=
MCFLAGS :=

LIBDIRS :=
LIBS := `pkg-config --libs libusb-1.0`

INCDIRS := -I . `pkg-config --cflags libusb-1.0`
SRCDIRS := . chips
ifeq ($(USB), winusb)
CFLAGS += -D_WIN32 -DUSE_WINUSB_DRV
LIBS := -lsetupapi -lhid -lwinusb
INCDIRS := -I .
else
LIBS := -lusb-1.0
INCDIRS := -I . -I /usr/include/libusb-1.0
endif
SRCDIRS := . chips usb

SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
Expand Down
14 changes: 10 additions & 4 deletions Makefile.win
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

CROSS ?= x86_64-w64-mingw32-
USB ?= libusb

AS := $(CROSS)gcc -x assembler-with-cpp
CC := $(CROSS)gcc
Expand All @@ -23,10 +24,15 @@ ODFLAGS :=
MCFLAGS :=

LIBDIRS :=
LIBS := -L/usr/x86_64-w64-mingw32/lib -lusb-1.0

INCDIRS := -I . -I /usr/x86_64-w64-mingw32/include/libusb-1.0
SRCDIRS := . chips
ifeq ($(USB), winusb)
CFLAGS += -D_WIN32 -DUSE_WINUSB_DRV
LIBS := -lsetupapi -lhid -lwinusb
INCDIRS := -I .
else
LIBS := -lusb-1.0
INCDIRS := -I . -I /usr/include/libusb-1.0
endif
SRCDIRS := . chips usb

SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
Expand Down
94 changes: 94 additions & 0 deletions chips/t153.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <fel.h>


static int chip_detect(struct xfel_ctx_t * ctx, uint32_t id)
{
if(id == 0x00192200)
{
return 1;
}
return 0;
}

static uint32_t payload_read32(struct xfel_ctx_t * ctx, uint32_t addr)
{
static const uint8_t payload[] = {
0x00, 0x00, 0xa0, 0xe3, 0x17, 0x0f, 0x08, 0xee, 0x15, 0x0f, 0x07, 0xee,
0xd5, 0x0f, 0x07, 0xee, 0x9a, 0x0f, 0x07, 0xee, 0x95, 0x0f, 0x07, 0xee,
0xff, 0xff, 0xff, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 0x0c, 0x10, 0x8f, 0xe2,
0x00, 0x20, 0x90, 0xe5, 0x00, 0x20, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
};
uint32_t adr = cpu_to_le32(addr);
uint32_t val;

fel_write(ctx, ctx->version.scratchpad, (void *)payload, sizeof(payload));
fel_write(ctx, ctx->version.scratchpad + sizeof(payload), (void *)&adr, sizeof(adr));
fel_exec(ctx, ctx->version.scratchpad);
fel_read(ctx, ctx->version.scratchpad + sizeof(payload) + sizeof(adr), (void *)&val, sizeof(val));
return le32_to_cpu(val);
}

static void payload_write32(struct xfel_ctx_t * ctx, uint32_t addr, uint32_t val)
{
static const uint8_t payload[] = {
0x00, 0x00, 0xa0, 0xe3, 0x17, 0x0f, 0x08, 0xee, 0x15, 0x0f, 0x07, 0xee,
0xd5, 0x0f, 0x07, 0xee, 0x9a, 0x0f, 0x07, 0xee, 0x95, 0x0f, 0x07, 0xee,
0xff, 0xff, 0xff, 0xea, 0x08, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x9f, 0xe5,
0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
};
uint32_t params[2] = {
cpu_to_le32(addr),
cpu_to_le32(val),
};

fel_write(ctx, ctx->version.scratchpad, (void *)payload, sizeof(payload));
fel_write(ctx, ctx->version.scratchpad + sizeof(payload), (void *)params, sizeof(params));
fel_exec(ctx, ctx->version.scratchpad);
}

static int chip_reset(struct xfel_ctx_t * ctx)
{
return 0;
}

static int chip_sid(struct xfel_ctx_t * ctx, char * sid)
{
return 0;
}

static int chip_jtag(struct xfel_ctx_t * ctx)
{
return 0;
}

static int chip_ddr(struct xfel_ctx_t * ctx, const char * type)
{
return 0;
}

static int chip_spi_init(struct xfel_ctx_t * ctx, uint32_t * swapbuf, uint32_t * swaplen, uint32_t * cmdlen)
{
return 0;
}

static int chip_spi_run(struct xfel_ctx_t * ctx, uint8_t * cbuf, uint32_t clen)
{
return 0;
}

static int chip_extra(struct xfel_ctx_t * ctx, int argc, char * argv[])
{
return 0;
}

struct chip_t t153 = {
.name = "T153",
.detect = chip_detect,
.reset = chip_reset,
.sid = chip_sid,
.jtag = chip_jtag,
.ddr = chip_ddr,
.spi_init = chip_spi_init,
.spi_run = chip_spi_run,
.extra = chip_extra,
};
121 changes: 5 additions & 116 deletions fel.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <fel.h>
#include <usb.h>

extern struct chip_t a10;
extern struct chip_t a13_a10s_r8;
Expand Down Expand Up @@ -32,6 +33,7 @@ extern struct chip_t a733;
extern struct chip_t t536;
extern struct chip_t a537_a333;
extern struct chip_t h135;
extern struct chip_t t153;


static struct chip_t * chips[] = {
Expand Down Expand Up @@ -67,95 +69,16 @@ static struct chip_t * chips[] = {
&t536,
&a537_a333,
&h135,
&t153,
};

struct usb_request_t {
char magic[8];
uint32_t length;
uint32_t unknown1;
uint16_t request;
uint32_t length2;
char pad[10];
} __attribute__((packed));

struct fel_request_t {
uint32_t request;
uint32_t address;
uint32_t length;
uint32_t pad;
} __attribute__((packed));

static inline void usb_bulk_send(libusb_device_handle * hdl, int ep, const char * buf, size_t len)
{
size_t max_chunk = 128 * 1024;
size_t chunk;
int r, bytes;

while(len > 0)
{
chunk = len < max_chunk ? len : max_chunk;
r = libusb_bulk_transfer(hdl, ep, (void *)buf, chunk, &bytes, 10000);
if(r != 0)
{
printf("usb bulk send error\r\n");
exit(-1);
}
len -= bytes;
buf += bytes;
}
}

static inline void usb_bulk_recv(libusb_device_handle * hdl, int ep, char * buf, size_t len)
{
int r, bytes;

while(len > 0)
{
r = libusb_bulk_transfer(hdl, ep, (void *)buf, len, &bytes, 10000);
if(r != 0)
{
printf("usb bulk recv error\r\n");
exit(-1);
}
len -= bytes;
buf += bytes;
}
}

static inline void send_usb_request(struct xfel_ctx_t * ctx, int type, size_t length)
{
struct usb_request_t req = {
.magic = "AWUC",
.request = cpu_to_le16(type),
.length = cpu_to_le32(length),
.unknown1 = cpu_to_le32(0x0c000000)
};
req.length2 = req.length;
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)&req, sizeof(struct usb_request_t));
}

static inline void read_usb_response(struct xfel_ctx_t * ctx)
{
char buf[13];

usb_bulk_recv(ctx->hdl, ctx->epin, (char *)buf, sizeof(buf));
assert(strcmp(buf, "AWUS") == 0);
}

static inline void usb_write(struct xfel_ctx_t * ctx, const void * buf, size_t len)
{
send_usb_request(ctx, 0x12, len);
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)buf, len);
read_usb_response(ctx);
}

static inline void usb_read(struct xfel_ctx_t * ctx, const void * data, size_t len)
{
send_usb_request(ctx, 0x11, len);
usb_bulk_send(ctx->hdl, ctx->epin, (const char *)data, len);
read_usb_response(ctx);
}

static inline void send_fel_request(struct xfel_ctx_t * ctx, int type, uint32_t addr, uint32_t length)
{
struct fel_request_t req = {
Expand Down Expand Up @@ -195,43 +118,9 @@ static inline int fel_version(struct xfel_ctx_t * ctx)

int fel_init(struct xfel_ctx_t * ctx)
{
if(ctx && ctx->hdl)
if(usb_init(ctx))
{
struct libusb_config_descriptor * config;
int if_idx, set_idx, ep_idx;
const struct libusb_interface * iface;
const struct libusb_interface_descriptor * setting;
const struct libusb_endpoint_descriptor * ep;

if(libusb_kernel_driver_active(ctx->hdl, 0))
libusb_detach_kernel_driver(ctx->hdl, 0);

if(libusb_claim_interface(ctx->hdl, 0) == 0)
{
if(libusb_get_active_config_descriptor(libusb_get_device(ctx->hdl), &config) == 0)
{
for(if_idx = 0; if_idx < config->bNumInterfaces; if_idx++)
{
iface = config->interface + if_idx;
for(set_idx = 0; set_idx < iface->num_altsetting; set_idx++)
{
setting = iface->altsetting + set_idx;
for(ep_idx = 0; ep_idx < setting->bNumEndpoints; ep_idx++)
{
ep = setting->endpoint + ep_idx;
if((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK)
continue;
if((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
ctx->epin = ep->bEndpointAddress;
else
ctx->epout = ep->bEndpointAddress;
}
}
}
libusb_free_config_descriptor(config);
return fel_version(ctx);
}
}
return fel_version(ctx);
}
return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion fel.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ struct xfel_ctx_t;
struct chip_t;

struct xfel_ctx_t {
libusb_device_handle * hdl;
void *hdl;
char *dev_name;
int epout;
int epin;
struct {
Expand Down
28 changes: 6 additions & 22 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <ecdsa256.h>
#include <spinor.h>
#include <spinand.h>
#include <libusb.h>
#include <usb.h>

static void usage(void)
{
Expand Down Expand Up @@ -52,30 +52,16 @@ int main(int argc, char * argv[])
}
}

libusb_device ** list = NULL;
libusb_context * context = NULL;
libusb_init(&context);
int count = libusb_get_device_list(context, &list);
for(int i = 0; i < count; i++)
if(!usb_open(&ctx))
{
libusb_device * device = list[i];
struct libusb_device_descriptor desc;
if(libusb_get_device_descriptor(device, &desc) != 0)
printf("ERROR: Can't get device list\r\n");
if((desc.idVendor == 0x1f3a) && (desc.idProduct == 0xefe8))
{
if(libusb_open(device, &ctx.hdl) != 0)
printf("ERROR: Can't connect to device\r\n");
break;
}
printf("ERROR: Can't connect to device\r\n");
return -1;
}

if(!fel_init(&ctx))
{
printf("ERROR: No FEL device found!\r\n");
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(NULL);
usb_close(&ctx);
return -1;
}
if(!strcmp(argv[1], "version"))
Expand Down Expand Up @@ -433,9 +419,7 @@ int main(int argc, char * argv[])
}
else
usage();
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(NULL);
usb_close(&ctx);

return 0;
}
Loading