/* * This file is part of the Black Magic Debug project. * * Copyright (C) 2011 Black Sphere Technologies Ltd. * Written by Gareth McMullin * * 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 . */ #include #include #ifdef WIN32 # include #else # include #endif #include #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 \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) && (dev->descriptor.idVendor != 0x1d50)) 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) || (dev->descriptor.idProduct == 0x6018)) && !strcmp(man, "Black Sphere Technologies")) return dev; if (((dev->descriptor.idProduct == 0xDF11) || (dev->descriptor.idProduct == 0x6017)) && !strcmp(man, "Black Sphere Technologies")) 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; *interface = iface->bInterfaceNumber; 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"); #ifdef WIN32 system("pause"); #endif 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(5000); #else sleep(5); #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); assert(stm32_mem_erase(handle, iface, LOAD_ADDRESS + offset) == 0); 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"); #ifdef WIN32 system("pause"); #endif return 0; }