summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/sbloader.c')
-rw-r--r--utils/imxtools/sbloader.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/utils/imxtools/sbloader.c b/utils/imxtools/sbloader.c
index ba4645f8ab..e1534ea7d5 100644
--- a/utils/imxtools/sbloader.c
+++ b/utils/imxtools/sbloader.c
@@ -40,17 +40,30 @@ void put32be(uint8_t *buf, uint32_t i)
*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 ret;
- uint8_t msg[0x20];
- uint8_t *p;
FILE *f;
int i, xfer_size, nr_xfers, recv_size;
if(argc != 3)
{
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;
}
@@ -67,12 +80,19 @@ int main(int argc, char **argv)
libusb_init(NULL);
libusb_set_debug(NULL, 3);
-
- /* MX23 */
- dev = libusb_open_device_with_vid_pid(NULL, 0x066F, 0x3780);
- if(dev == NULL)
- /* MX28 */
- dev = libusb_open_device_with_vid_pid(NULL, 0x15A2, 0x004F);
+
+ for(unsigned i = 0; i < sizeof(g_dev_info) / sizeof(g_dev_info[0]); i++)
+ {
+ dev = libusb_open_device_with_vid_pid(NULL,
+ g_dev_info[i].vendor_id, g_dev_info[i].product_id);
+ if(dev == NULL)
+ continue;
+ 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)
{
printf("Cannot open device\n");
@@ -85,7 +105,7 @@ int main(int argc, char **argv)
libusb_claim_interface (dev, 0);
libusb_claim_interface (dev, 4);
- if (!dev)
+ if(!dev)
{
printf("No dev\n");
exit(1);
@@ -113,37 +133,36 @@ int main(int argc, char **argv)
}
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
- *p++ = 'B'; // Signature
+ /* Command block wrapper */
+ *p++ = 'B'; /* Signature */
*p++ = 'L';
*p++ = 'T';
*p++ = 'C';
- put32le(p, 0x1); // I guess version or sub-command
+ put32le(p, 0x1); /* Tag */
p += 4;
- put32le(p, size); // Payload size
-
- // The second command starts at 0x20
-
- p = &msg[0x10];
+ put32le(p, size); /* Payload size */
+ p += 4;
+ *p++ = 0; /* Flags (host to device) */
+ p += 2; /* Reserved */
- *p++ = 0x02; // Start upload
- put32be(p, size); // Payload size, again
+ /* Command descriptor block */
+ *p++ = 0x02; /* Firmware download */
+ put32be(p, size); /* Download size */
ret = libusb_control_transfer(dev,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0,
- msg, 0x20, 1000);
+ xfer_buf, xfer_size + 1, 1000);
if(ret < 0)
{
printf("transfer error at init step\n");
return 1;
}
- uint8_t *xfer_buf = malloc(1 + xfer_size);
-
for(i = 0; i < nr_xfers; i++)
{
xfer_buf[0] = 0x2;