1
0
Fork 0
forked from len0rd/rockbox

sbloader: always send packets of size xfer_size (even the first). Also maintain a table of known transfer sizes. In particular stmp3770 uses 48 instead of 1024.

Change-Id: I08dddc76c251aeeaaa3b46c9466f9be54c3d4a45
This commit is contained in:
Amaury Pouly 2012-01-27 20:06:42 +01:00
parent d32891fa59
commit 28a10ec490

View file

@ -40,17 +40,30 @@ void put32be(uint8_t *buf, uint32_t i)
*buf++ = i & 0xff; *buf++ = i & 0xff;
} }
struct dev_info_t
{
uint16_t vendor_id;
uint16_t product_id;
unsigned xfer_size;
};
struct dev_info_t g_dev_info[] =
{
{0x066f, 0x3780, 1024}, /* i.MX233 / STMP3780 */
{0x066f, 0x3770, 48}, /* STMP3770 */
{0x15A2, 0x004F, 1024}, /* i.MX28 */
};
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int ret; int ret;
uint8_t msg[0x20];
uint8_t *p;
FILE *f; FILE *f;
int i, xfer_size, nr_xfers, recv_size; int i, xfer_size, nr_xfers, recv_size;
if(argc != 3) if(argc != 3)
{ {
printf("usage: %s <xfer size> <file>\n", argv[0]); printf("usage: %s <xfer size> <file>\n", argv[0]);
printf("If <xfer size> is set to zero, the preferred one is used.\n");
return 1; return 1;
} }
@ -68,11 +81,18 @@ int main(int argc, char **argv)
libusb_set_debug(NULL, 3); libusb_set_debug(NULL, 3);
/* MX23 */ for(unsigned i = 0; i < sizeof(g_dev_info) / sizeof(g_dev_info[0]); i++)
dev = libusb_open_device_with_vid_pid(NULL, 0x066F, 0x3780); {
dev = libusb_open_device_with_vid_pid(NULL,
g_dev_info[i].vendor_id, g_dev_info[i].product_id);
if(dev == NULL) if(dev == NULL)
/* MX28 */ continue;
dev = libusb_open_device_with_vid_pid(NULL, 0x15A2, 0x004F); if(xfer_size == 0)
xfer_size = g_dev_info[i].xfer_size;
printf("Found a match for %04x:%04x\n",
g_dev_info[i].vendor_id, g_dev_info[i].product_id);
break;
}
if(dev == NULL) if(dev == NULL)
{ {
printf("Cannot open device\n"); printf("Cannot open device\n");
@ -113,37 +133,36 @@ int main(int argc, char **argv)
} }
fclose(f); fclose(f);
memset(msg, 0, 0x20); uint8_t *xfer_buf = malloc(1 + xfer_size);
uint8_t *p = xfer_buf;
p = msg; *p++ = 0x01; /* Report id */
*p++ = 0x01; // Init upload command /* Command block wrapper */
*p++ = 'B'; // Signature *p++ = 'B'; /* Signature */
*p++ = 'L'; *p++ = 'L';
*p++ = 'T'; *p++ = 'T';
*p++ = 'C'; *p++ = 'C';
put32le(p, 0x1); // I guess version or sub-command put32le(p, 0x1); /* Tag */
p += 4; p += 4;
put32le(p, size); // Payload size put32le(p, size); /* Payload size */
p += 4;
*p++ = 0; /* Flags (host to device) */
p += 2; /* Reserved */
// The second command starts at 0x20 /* Command descriptor block */
*p++ = 0x02; /* Firmware download */
p = &msg[0x10]; put32be(p, size); /* Download size */
*p++ = 0x02; // Start upload
put32be(p, size); // Payload size, again
ret = libusb_control_transfer(dev, ret = libusb_control_transfer(dev,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0,
msg, 0x20, 1000); xfer_buf, xfer_size + 1, 1000);
if(ret < 0) if(ret < 0)
{ {
printf("transfer error at init step\n"); printf("transfer error at init step\n");
return 1; return 1;
} }
uint8_t *xfer_buf = malloc(1 + xfer_size);
for(i = 0; i < nr_xfers; i++) for(i = 0; i < nr_xfers; i++)
{ {
xfer_buf[0] = 0x2; xfer_buf[0] = 0x2;