#include #include "libusb.h" #define DFU_DNLOAD 0x01 #define DFU_UPLOAD 0x02 #define DFU_GETSTATUS 0x03 #define DFU_CLRSTATUS 0x04 #define BLOCK_SIZE 2048 static void print_devs(libusb_device **devs) { libusb_device *dev; int i = 0, j = 0; uint8_t path[8]; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { fprintf(stderr, "failed to get device descriptor"); return; } printf("%04x:%04x (bus %d, device %d)", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev)); r = libusb_get_port_numbers(dev, path, sizeof(path)); if (r > 0) { printf(" path: %d", path[0]); for (j = 1; j < r; j++) printf(".%d", path[j]); } printf("\n"); } } static int test_device(uint16_t vid, uint16_t pid) { libusb_device_handle *handle; libusb_device *dev; uint8_t bus, port_path[8]; struct libusb_bos_descriptor *bos_desc; struct libusb_config_descriptor *conf_desc; const struct libusb_endpoint_descriptor *endpoint; int i, j, k, r; int iface, nb_ifaces, first_iface = -1; struct libusb_device_descriptor dev_desc; const char* const speed_name[6] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)", "10000 Mbit/s (USB SuperSpeedPlus)" }; char string[128]; uint8_t string_index[3]; // indexes of the string descriptors uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints printf("Opening device %04X:%04X...\n", vid, pid); handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { printf(" Failed.\n"); return -1; } dev = libusb_get_device(handle); bus = libusb_get_bus_number(dev); r = libusb_get_port_numbers(dev, port_path, sizeof(port_path)); if (r > 0) { printf("\nDevice properties:\n"); printf(" bus number: %d\n", bus); printf(" port path: %d", port_path[0]); for (i=1; i%d", port_path[i]); } printf(" (from root hub)\n"); } r = libusb_get_device_speed(dev); if ((r<0) || (r>5)) r=0; printf(" speed: %s\n", speed_name[r]); printf("Closing device...\n"); libusb_close(handle); return 0; } static uint8_t clear_status(libusb_device_handle *handle){ uint8_t r; uint8_t num_bytes = 0; //wLength = 6 on DFU_CLRSTATUS. r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, //bmRequestType DFU_CLRSTATUS, //bRequest 0, //wValue (wBlockNum) 0, //wIndex (interface, 0) NULL, //data buffer num_bytes, //wLength 100 //timeout (ms) ); if (r < 0) printf("error: clear_status() control transfer failed\n"); return r; } static uint8_t get_status(libusb_device_handle *handle, uint8_t * buffer){ uint8_t r; uint8_t num_bytes = 6; //wLength = 6 on DFU_GETSTATUS. r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, //bmRequestType DFU_GETSTATUS, //bRequest 0, //wValue (wBlockNum) 0, //wIndex (interface, 0) buffer, //data buffer num_bytes, //wLength 100 //timeout (ms) ); if (r < 0) printf("error: get_status() control transfer failed\n"); return r; } //Address = ((wBlockNum – 2) × wTransferSize) + Address_Pointer //By default, Address_Pointer is at start of flash (0x08000000) static uint8_t read_block(libusb_device_handle *handle, uint8_t * buffer, uint8_t block){ uint8_t r; uint16_t num_bytes = BLOCK_SIZE; //wTransferSize (in device descriptor, 2048 for stm32f042) r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, //bmRequestType DFU_UPLOAD, //bRequest block, //wValue (wBlockNum) 0, //wIndex (interface, 0) buffer, //data buffer num_bytes, //wLength 500 //timeout (ms) ); if (r < 0) printf("error: read_block() control transfer failed\n"); return r; } static void print_block(uint8_t * buffer, uint32_t start_address){ for (uint16_t i = 0; i < BLOCK_SIZE; i += 16) { printf("0x%08X: ", start_address + i); // Print the row of 16 bytes for (uint16_t j = 0; j < 16; j += 4) { printf("%02x%02x%02x%02x ", buffer[i+j+3], buffer[i+j+2], buffer[i+j+1], buffer[i+j+0]); } printf("\n"); } } int main(void) { //TEST CONNECTION libusb_device **devs; int r; ssize_t cnt; r = libusb_init(NULL); if (r < 0) return r; cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0){ libusb_exit(NULL); return (int) cnt; } print_devs(devs); //0483:df11 test_device(0x0483, 0xdf11); int num_bytes = 6; uint8_t status[6]; uint8_t data[BLOCK_SIZE]; uint32_t start_address = 0x08000000; libusb_device_handle *handle; printf("Opening device\n"); handle = libusb_open_device_with_vid_pid(NULL, 0x0483, 0xdf11); //0483:df11 //CLEAR AND GET STATUS clear_status(handle); get_status(handle, status); //READ FIRST BLOCK read_block(handle, data, 2); print_block(data, start_address); printf("\n"); //READ SECOND BLOCK read_block(handle, data, 3); print_block(data, start_address + BLOCK_SIZE); //CLEAR STATUS clear_status(handle); libusb_free_device_list(devs, 1); libusb_exit(NULL); return 0; }