aboutsummaryrefslogtreecommitdiff
path: root/upgrade/main.c
diff options
context:
space:
mode:
authorGareth McMullin2012-01-18 20:45:18 +1300
committerGareth McMullin2012-01-18 20:46:35 +1300
commitf2f5fd2fa13f74560bb2cfd88417ad6c1e230988 (patch)
tree01a331d978102254287ea1cacbe3fd5a0d2768b8 /upgrade/main.c
parenta7f14e3cc008e2ef927dd2b3bc41f37cf1c21add (diff)
Added unfinished, untested upgrade tool.
Diffstat (limited to 'upgrade/main.c')
-rw-r--r--upgrade/main.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/upgrade/main.c b/upgrade/main.c
new file mode 100644
index 0000000..bdb1b6b
--- /dev/null
+++ b/upgrade/main.c
@@ -0,0 +1,160 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2011 Black Sphere Technologies Ltd.
+ * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <usb.h>
+#include <string.h>
+
+#include "dfu.h"
+#include "stm32mem.h"
+#include "bindata.h"
+
+#define VERSION "1.0"
+
+#define LOAD_ADDRESS 0x8002000
+
+void banner(void)
+{
+ puts("\nBlack Magic Probe -- Firmware Upgrade Utility -- Version " VERSION);
+ puts("Copyright (C) 2011 Black Sphere Technologies Ltd.");
+ puts("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n");
+}
+
+
+struct usb_device * find_dev(void)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ struct usb_dev_handle *handle;
+ char man[40];
+ char prod[40];
+
+ usb_find_busses();
+ usb_find_devices();
+
+ for(bus = usb_get_busses(); bus; bus = bus->next) {
+ for(dev = bus->devices; dev; dev = dev->next) {
+ /* Check for ST Microelectronics vendor ID */
+ if(dev->descriptor.idVendor != 0x483) continue;
+
+ handle = usb_open(dev);
+ usb_get_string_simple(handle, dev->descriptor.iManufacturer, man,
+ sizeof(man));
+ usb_get_string_simple(handle, dev->descriptor.iProduct, prod,
+ sizeof(prod));
+#if 0
+ printf("%s:%s [%04X:%04X] %s : %s\n", bus->dirname, dev->filename,
+ dev->descriptor.idVendor, dev->descriptor.idProduct, man, prod);
+#endif
+ usb_close(handle);
+
+ if((dev->descriptor.idProduct == 0x5740) &&
+ !strcmp(man, "Black Sphere Technologies") &&
+ !strcmp(prod, "Black Magic Probe"))
+ return dev;
+
+ if((dev->descriptor.idProduct == 0xDF11) &&
+ !strcmp(man, "Black Sphere Technologies") &&
+ !strcmp(prod, "Black Magic Probe (Upgrade)"))
+ return dev;
+ }
+ }
+ return NULL;
+}
+
+usb_dev_handle * get_dfu_interface(struct usb_device *dev, uint16_t *interface)
+{
+ int i, j, k;
+ struct usb_config_descriptor *config;
+ struct usb_interface_descriptor *iface;
+
+ usb_dev_handle *handle;
+
+ for(i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+ config = &dev->config[i];
+
+ for(j = 0; j < config->bNumInterfaces; j++) {
+ for(k = 0; k < config->interface[j].num_altsetting; k++) {
+ iface = &config->interface[j].altsetting[k];
+ if((iface->bInterfaceClass == 0xFE) &&
+ (iface->bInterfaceSubClass = 0x01)) {
+ handle = usb_open(dev);
+ //usb_set_configuration(handle, i);
+ usb_claim_interface(handle, j);
+ //usb_set_altinterface(handle, k);
+ *interface = j;
+ return handle;
+ }
+ }
+
+ }
+ }
+ return NULL;
+}
+
+int main(void)
+{
+ struct usb_device *dev;
+ usb_dev_handle *handle;
+ uint16_t iface;
+ int state;
+ uint32_t offset;
+
+ banner();
+ usb_init();
+
+retry:
+ if(!(dev = find_dev()) || !(handle = get_dfu_interface(dev, &iface))) {
+ puts("FATAL: No compatible device found!\n");
+ return -1;
+ }
+
+ state = dfu_getstate(handle, iface);
+ if((state < 0) || (state == STATE_APP_IDLE)) {
+ puts("Resetting device in firmware upgrade mode...");
+ dfu_detach(handle, iface, 1000);
+ usb_release_interface(handle, iface);
+ usb_close(handle);
+#ifdef WIN32
+ Sleep(3000);
+#else
+ sleep(1);
+#endif
+ goto retry;
+ }
+ printf("Found device at %s:%s\n", dev->bus->dirname, dev->filename);
+
+ dfu_makeidle(handle, iface);
+
+ for(offset = 0; offset < bindatalen; offset += 1024) {
+ printf("Progress: %d%%\r", (offset*100)/bindatalen);
+ fflush(stdout);
+ stm32_mem_erase(handle, iface, LOAD_ADDRESS + offset);
+ stm32_mem_write(handle, iface, (void*)&bindata[offset], 1024);
+ }
+ stm32_mem_manifest(handle, iface);
+
+ usb_release_interface(handle, iface);
+ usb_close(handle);
+
+ puts("All operations complete!\n");
+
+ return 0;
+}
+