diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-01-27 20:06:42 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-01-27 20:08:33 +0100 |
commit | 28a10ec4906d5a1f990046f146d161f9c49e89ad (patch) | |
tree | 56b7dfddccd80f2fc54604938b68d20a384acac2 /utils | |
parent | d32891fa5940bb4eda47e513c2c7d0be27f38ecb (diff) | |
download | rockbox-28a10ec4906d5a1f990046f146d161f9c49e89ad.tar.gz rockbox-28a10ec4906d5a1f990046f146d161f9c49e89ad.zip |
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
Diffstat (limited to 'utils')
-rw-r--r-- | utils/imxtools/sbloader.c | 67 |
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) | |||
40 | *buf++ = i & 0xff; | 40 | *buf++ = i & 0xff; |
41 | } | 41 | } |
42 | 42 | ||
43 | struct dev_info_t | ||
44 | { | ||
45 | uint16_t vendor_id; | ||
46 | uint16_t product_id; | ||
47 | unsigned xfer_size; | ||
48 | }; | ||
49 | |||
50 | struct dev_info_t g_dev_info[] = | ||
51 | { | ||
52 | {0x066f, 0x3780, 1024}, /* i.MX233 / STMP3780 */ | ||
53 | {0x066f, 0x3770, 48}, /* STMP3770 */ | ||
54 | {0x15A2, 0x004F, 1024}, /* i.MX28 */ | ||
55 | }; | ||
56 | |||
43 | int main(int argc, char **argv) | 57 | int main(int argc, char **argv) |
44 | { | 58 | { |
45 | int ret; | 59 | int ret; |
46 | uint8_t msg[0x20]; | ||
47 | uint8_t *p; | ||
48 | FILE *f; | 60 | FILE *f; |
49 | int i, xfer_size, nr_xfers, recv_size; | 61 | int i, xfer_size, nr_xfers, recv_size; |
50 | 62 | ||
51 | if(argc != 3) | 63 | if(argc != 3) |
52 | { | 64 | { |
53 | printf("usage: %s <xfer size> <file>\n", argv[0]); | 65 | printf("usage: %s <xfer size> <file>\n", argv[0]); |
66 | printf("If <xfer size> is set to zero, the preferred one is used.\n"); | ||
54 | return 1; | 67 | return 1; |
55 | } | 68 | } |
56 | 69 | ||
@@ -67,12 +80,19 @@ int main(int argc, char **argv) | |||
67 | libusb_init(NULL); | 80 | libusb_init(NULL); |
68 | 81 | ||
69 | libusb_set_debug(NULL, 3); | 82 | libusb_set_debug(NULL, 3); |
70 | 83 | ||
71 | /* MX23 */ | 84 | for(unsigned i = 0; i < sizeof(g_dev_info) / sizeof(g_dev_info[0]); i++) |
72 | dev = libusb_open_device_with_vid_pid(NULL, 0x066F, 0x3780); | 85 | { |
73 | if(dev == NULL) | 86 | dev = libusb_open_device_with_vid_pid(NULL, |
74 | /* MX28 */ | 87 | g_dev_info[i].vendor_id, g_dev_info[i].product_id); |
75 | dev = libusb_open_device_with_vid_pid(NULL, 0x15A2, 0x004F); | 88 | if(dev == NULL) |
89 | continue; | ||
90 | if(xfer_size == 0) | ||
91 | xfer_size = g_dev_info[i].xfer_size; | ||
92 | printf("Found a match for %04x:%04x\n", | ||
93 | g_dev_info[i].vendor_id, g_dev_info[i].product_id); | ||
94 | break; | ||
95 | } | ||
76 | if(dev == NULL) | 96 | if(dev == NULL) |
77 | { | 97 | { |
78 | printf("Cannot open device\n"); | 98 | printf("Cannot open device\n"); |
@@ -85,7 +105,7 @@ int main(int argc, char **argv) | |||
85 | libusb_claim_interface (dev, 0); | 105 | libusb_claim_interface (dev, 0); |
86 | libusb_claim_interface (dev, 4); | 106 | libusb_claim_interface (dev, 4); |
87 | 107 | ||
88 | if (!dev) | 108 | if(!dev) |
89 | { | 109 | { |
90 | printf("No dev\n"); | 110 | printf("No dev\n"); |
91 | exit(1); | 111 | exit(1); |
@@ -113,37 +133,36 @@ int main(int argc, char **argv) | |||
113 | } | 133 | } |
114 | fclose(f); | 134 | fclose(f); |
115 | 135 | ||
116 | memset(msg, 0, 0x20); | 136 | uint8_t *xfer_buf = malloc(1 + xfer_size); |
137 | uint8_t *p = xfer_buf; | ||
117 | 138 | ||
118 | p = msg; | 139 | *p++ = 0x01; /* Report id */ |
119 | 140 | ||
120 | *p++ = 0x01; // Init upload command | 141 | /* Command block wrapper */ |
121 | *p++ = 'B'; // Signature | 142 | *p++ = 'B'; /* Signature */ |
122 | *p++ = 'L'; | 143 | *p++ = 'L'; |
123 | *p++ = 'T'; | 144 | *p++ = 'T'; |
124 | *p++ = 'C'; | 145 | *p++ = 'C'; |
125 | put32le(p, 0x1); // I guess version or sub-command | 146 | put32le(p, 0x1); /* Tag */ |
126 | p += 4; | 147 | p += 4; |
127 | put32le(p, size); // Payload size | 148 | put32le(p, size); /* Payload size */ |
128 | 149 | p += 4; | |
129 | // The second command starts at 0x20 | 150 | *p++ = 0; /* Flags (host to device) */ |
130 | 151 | p += 2; /* Reserved */ | |
131 | p = &msg[0x10]; | ||
132 | 152 | ||
133 | *p++ = 0x02; // Start upload | 153 | /* Command descriptor block */ |
134 | put32be(p, size); // Payload size, again | 154 | *p++ = 0x02; /* Firmware download */ |
155 | put32be(p, size); /* Download size */ | ||
135 | 156 | ||
136 | ret = libusb_control_transfer(dev, | 157 | ret = libusb_control_transfer(dev, |
137 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0, | 158 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0, |
138 | msg, 0x20, 1000); | 159 | xfer_buf, xfer_size + 1, 1000); |
139 | if(ret < 0) | 160 | if(ret < 0) |
140 | { | 161 | { |
141 | printf("transfer error at init step\n"); | 162 | printf("transfer error at init step\n"); |
142 | return 1; | 163 | return 1; |
143 | } | 164 | } |
144 | 165 | ||
145 | uint8_t *xfer_buf = malloc(1 + xfer_size); | ||
146 | |||
147 | for(i = 0; i < nr_xfers; i++) | 166 | for(i = 0; i < nr_xfers; i++) |
148 | { | 167 | { |
149 | xfer_buf[0] = 0x2; | 168 | xfer_buf[0] = 0x2; |